diff --git a/AppleSAWS.pro b/AppleSAWS.pro
index c5454a6..5ebe0ab 100644
--- a/AppleSAWS.pro
+++ b/AppleSAWS.pro
@@ -55,7 +55,9 @@ SOURCES += \
src/ui/widgets/characterwidget.cpp \
src/ui/viewers/applesoftfiledetailviewer.cpp \
src/ui/widgets/hexconverter.cpp \
- src/ui/viewers/viewerbase.cpp
+ src/ui/viewers/viewerbase.cpp \
+ src/ui/widgets/CharacterSetExplorer.cpp \
+ src/ui/widgets/HiresScreenWidget.cpp
HEADERS += \
@@ -93,7 +95,9 @@ HEADERS += \
src/ui/widgets/hexconverter.h \
src/ui/widgets/hrcgcontrolsinfo.h \
src/ui/viewers/viewerbase.h \
- src/ui/viewers/fileviewerinterface.h
+ src/ui/viewers/fileviewerinterface.h \
+ src/ui/widgets/CharacterSetExplorer.h \
+ src/ui/widgets/HiresScreenWidget.h
FORMS += \
src/ui/catalogwidget.ui \
@@ -105,4 +109,5 @@ FORMS += \
src/ui/viewers/applesoftfiledetailviewer.ui \
src/ui/widgets/hexconverter.ui \
src/ui/widgets/hrcgcontrolsinfo.ui \
- src/ui/viewers/viewerbase.ui
+ src/ui/viewers/viewerbase.ui \
+ src/ui/widgets/CharacterSetExplorer.ui
diff --git a/src/ui/viewers/hexdumpviewer.ui b/src/ui/viewers/hexdumpviewer.ui
index 93de795..ec8dc2c 100644
--- a/src/ui/viewers/hexdumpviewer.ui
+++ b/src/ui/viewers/hexdumpviewer.ui
@@ -6,8 +6,8 @@
0
0
- 107
- 117
+ 538
+ 483
diff --git a/src/ui/viewers/hiresviewwidget.cxx b/src/ui/viewers/hiresviewwidget.cxx
index 5083b49..546a246 100644
--- a/src/ui/viewers/hiresviewwidget.cxx
+++ b/src/ui/viewers/hiresviewwidget.cxx
@@ -6,6 +6,7 @@
#include
#include
#include
+#include
#include
@@ -13,285 +14,14 @@
HiresViewWidget::HiresViewWidget(QWidget *parent) :
FileViewerInterface(parent)
{
+ QGridLayout *gv = new QGridLayout(this);
+ setLayout(gv);
+ hrsw = new HiresScreenWidget(this);
+ gv->addWidget(hrsw);
+
resize(561,384);
- QSettings settings;
- m_viewMode = static_cast(settings.value("HiresViewWidget.ViewMode",Color2).toInt());
- m_showScanLines = settings.value("HiresViewWidget.ShowScanLines",true).toBool();
-
- if (m_rowTable == 0) { makeOffsetTable(); }
-
- m_pixmap = QPixmap(561,384);
- QPainter painter(&m_pixmap);
- painter.setBrush(Qt::black);
- painter.drawRect(0,0,this->width(),this->height());
-
- formatGroup = new QActionGroup(this);
-
- monochromeAction = new QAction("Monochrome Display",this);
- monochromeAction->setCheckable(true);
- monochromeAction->setChecked(false);
- formatGroup->addAction(monochromeAction);
-
- ntscAction = new QAction("NTSC Display",this);
- ntscAction->setCheckable(true);
- ntscAction->setChecked(true);
- formatGroup->addAction(ntscAction);
-
- perPixelColorAction= new QAction("Per Pixel Color Display",this);
- perPixelColorAction->setCheckable(true);
- perPixelColorAction->setChecked(false);
- formatGroup->addAction(perPixelColorAction);
-
-
-
- showScanLinesAction = new QAction("Show Scan Lines",this);
- showScanLinesAction->setCheckable(true);
- showScanLinesAction->setChecked(m_showScanLines);
-
-
- connect(ntscAction, SIGNAL(toggled(bool)), this, SLOT(handleNtscAction(bool)));
- connect(monochromeAction, SIGNAL(toggled(bool)), this, SLOT(handleMonochromeAction(bool)));
- connect(perPixelColorAction, SIGNAL(toggled(bool)), this, SLOT(handlePerPixelColorAction(bool)));
-
- connect(showScanLinesAction, SIGNAL(toggled(bool)), this, SLOT(handleShowScanLinesAction(bool)));
-
}
-void HiresViewWidget::handleNtscAction(bool toggled) {
- if (toggled) {
- m_viewMode = Color2;
- update();
- }
- QSettings settings;
- settings.setValue("HiresViewWidget.ViewMode",m_viewMode);
-}
-
-void HiresViewWidget::handleMonochromeAction(bool toggled) {
- if (toggled) {
- m_viewMode = Monochrome;
- update();
- }
- QSettings settings;
- settings.setValue("HiresViewWidget.ViewMode",m_viewMode);
-}
-
-void HiresViewWidget::handlePerPixelColorAction(bool toggled) {
- if (toggled) {
- m_viewMode = Color1;
- update();
- }
- QSettings settings;
- settings.setValue("HiresViewWidget.ViewMode",m_viewMode);
-}
-
-void HiresViewWidget::handleShowScanLinesAction(bool toggled) {
- m_showScanLines = toggled;
- update();
- QSettings settings;
- settings.setValue("HiresViewWidget.ShowScanLines",toggled);
-}
-
-void HiresViewWidget::paintEvent(QPaintEvent *event)
-{
- Q_UNUSED(event);
-
- // if (m_pixmap.size() != this->size()) {
- // m_pixmap = m_pixmap.scaled(this->size(),Qt::KeepAspectRatio);
- // }
-
- drawPixmap();
-
- QPainter painter(this);
-
- QPixmap tmppixmap = m_pixmap;
-// tmppixmap = tmppixmap.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
-
- painter.drawPixmap(0,0,tmppixmap);
-}
-
-void HiresViewWidget::resizeEvent(QResizeEvent *)
-{
-
-}
-
-void HiresViewWidget::drawPixmap() {
-
- QPainter pmpainter(&m_pixmap);
-
- pmpainter.setBrush(Qt::black);
- pmpainter.setPen(Qt::black);
- pmpainter.drawRect(0,0,m_pixmap.width(),m_pixmap.height());
-
- if (m_viewMode == Monochrome)
- {
- pmpainter.setPen(Qt::white);
- pmpainter.setBrush(Qt::white);
-
- quint8 chunkCount = 0;
- // for (int idx = 0; idx < m_data.size() ; idx+=40) {
- int idx = 0;
- while (idx < m_data.size()) {
- int rowcol = findRowCol(idx);
- // int xoff = (rowcol / 10000) * 7;
- int yoff = (rowcol % 10000);
-
- QBitArray bits(561,false);
- int bitoffset = 0;
- bool lastbit = false;
-
- for (int jdx = 0; jdx < 40; jdx++)
- {
- quint8 byte = m_data[idx++];
- QBitArray dataBits = byteToBits(byte);
-
- bool highBit = dataBits.at(0);
-
- if (highBit) {
- bits[bitoffset++] = lastbit;
- }
-
- for (int xdx = 1; xdx < 7; xdx++) {
- bits[bitoffset++] = dataBits.at(xdx);
- bits[bitoffset++] = dataBits.at(xdx);
- }
- lastbit = dataBits.at(7);
- bits[bitoffset++] = dataBits.at(7);
- if (!highBit) {
- bits[bitoffset++] = dataBits.at(7);
- }
- }
-
-
- drawMonoLine(pmpainter, yoff*2, bits);
- if (!m_showScanLines) drawMonoLine(pmpainter, yoff*2+1, bits);
-
-
- chunkCount++;
- if (chunkCount == 3) {
- chunkCount = 0;
- idx+=8;
- }
-
- }
- } else if (m_viewMode == Color1) {
-
- pmpainter.setPen(Qt::white);
- pmpainter.setBrush(Qt::white);
-
- for (int idx = 0; idx < m_data.size() ; idx++) {
- int rowcol = findRowCol(idx);
-
- quint8 byte = m_data[idx];
-
- bool highBit = byte & 0x80;
-
- QColor oddColor = highBit? QColor(orangeColor) : QColor(greenColor);
- QColor evenColor = highBit? QColor(blueColor) : QColor(purpleColor);
-
- int xoff = (rowcol / 10000) * 7;
- int yoff = (rowcol % 10000)*2;
-
- quint8 cOffset = 0;// highBit?1:0;
-
- quint8 doubleScan = 0;
- if (!m_showScanLines)
- {
- doubleScan = 1;
- }
-
- pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
- pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
-
- if (byte & 0x01) { pmpainter.drawRect((cOffset+xoff*2)+0,yoff,1,doubleScan); }
-
- pmpainter.setPen(xoff & 0x01?evenColor:oddColor);
- pmpainter.setBrush(xoff & 0x01?evenColor:oddColor);
-
- if (byte & 0x02) { pmpainter.drawRect((cOffset+xoff*2)+2,yoff,1,doubleScan); }
-
- pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
- pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
-
- if (byte & 0x04) { pmpainter.drawRect((cOffset+xoff*2)+4,yoff,1,doubleScan); }
-
- pmpainter.setPen(xoff & 0x01?evenColor:oddColor);
- pmpainter.setBrush(xoff & 0x01?evenColor:oddColor);
-
- if (byte & 0x08) { pmpainter.drawRect((cOffset+xoff*2)+6,yoff,1,doubleScan); }
-
- pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
- pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
-
-
- if (byte & 0x10) { pmpainter.drawRect((cOffset+xoff*2)+8,yoff,1,doubleScan); }
-
- pmpainter.setPen(xoff & 0x01?evenColor:oddColor);
- pmpainter.setBrush(xoff & 0x01?evenColor:oddColor);
-
- if (byte & 0x20) { pmpainter.drawRect((cOffset+xoff*2)+10,yoff,1,doubleScan); }
-
- pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
- pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
-
-
- if (byte & 0x40) { pmpainter.drawRect((cOffset+xoff*2)+12,yoff,cOffset?0:1,doubleScan); }
-
-
-
- if (idx >= (280*192)) break;
- }
- } else if (m_viewMode == Color2) {
-
- pmpainter.setPen(Qt::white);
- pmpainter.setBrush(Qt::white);
-
- quint8 chunkCount = 0;
- // for (int idx = 0; idx < m_data.size() ; idx+=40) {
- int idx = 0;
- while (idx < m_data.size()) {
- int rowcol = findRowCol(idx);
- // int xoff = (rowcol / 10000) * 7;
- int yoff = (rowcol % 10000);
-
- QBitArray bits(561,false);
- int bitoffset = 0;
- bool lastbit = false;
-
- for (int jdx = 0; jdx < 40; jdx++)
- {
- quint8 byte = m_data[idx++];
- QBitArray dataBits = byteToBits(byte);
-
- bool highBit = dataBits.at(0);
-
- if (highBit) {
- bits[bitoffset++] = lastbit;
- }
-
- for (int xdx = 1; xdx < 7; xdx++) {
- bits[bitoffset++] = dataBits.at(xdx);
- bits[bitoffset++] = dataBits.at(xdx);
- }
- lastbit = dataBits.at(7);
- bits[bitoffset++] = dataBits.at(7);
- if (!highBit) {
- bits[bitoffset++] = dataBits.at(7);
- }
- }
-
- drawNtscLine(pmpainter, yoff*2, bits);
- if (!m_showScanLines) {
- drawNtscLine(pmpainter, yoff*2+1, bits);
- }
-
- chunkCount++;
- if (chunkCount == 3) {
- chunkCount = 0;
- idx+=8;
- }
- }
- }
-}
void HiresViewWidget::setFile(BinaryFile *file) {
m_file = file;
@@ -299,238 +29,17 @@ void HiresViewWidget::setFile(BinaryFile *file) {
QString title = QString("Image: %1").arg(m_file->filename());
setWindowTitle(title);
- setData(file->data());
-
+ hrsw->setData(file->data());
}
-void HiresViewWidget::setData(QByteArray data) {
- m_data = data;
-
- drawPixmap();
-}
-
-void HiresViewWidget::drawMonoLine(QPainter &painter, int lineNum, QBitArray data) {
- for (int idx = 0; idx < data.count(); idx++) {
-
- if (data.at(idx))
- {
- painter.setPen(Qt::white);
- } else {
- painter.setPen(Qt::black);
- }
-
-
- painter.drawPoint(idx,lineNum);
- }
-}
-
-QColor HiresViewWidget::getColorFromBits(QBitArray bits, quint8 phase)
-{
- quint8 bitval = (bits[0] * 0x08) +
- (bits[1] * 0x04) +
- (bits[2] * 0x02) +
- (bits[3] * 0x01);
-
- phase %= 4;
-
- //qDebug() << bits << phase;
-
-
- if (bitval == 0) { return blackColor; }
-
- if (bitval == 1 && phase == 0) return brownColor;
- if (bitval == 2 && phase == 1) return brownColor;
- if (bitval == 4 && phase == 2) return brownColor;
- if (bitval == 8 && phase == 3) return brownColor;
-
- if (bitval == 2 && phase == 0) return darkGreenColor;
- if (bitval == 4 && phase == 1) return darkGreenColor;
- if (bitval == 8 && phase == 2) return darkGreenColor;
- if (bitval == 1 && phase == 3) return darkGreenColor;
-
- if (bitval == 3 && phase == 0) return greenColor;
- if (bitval == 6 && phase == 1) return greenColor;
- if (bitval == 12 && phase == 2) return greenColor;
- if (bitval == 9 && phase == 3) return greenColor;
-
- if (bitval == 4 && phase == 0) return darkBlueColor;
- if (bitval == 8 && phase == 1) return darkBlueColor;
- if (bitval == 1 && phase == 2) return darkBlueColor;
- if (bitval == 2 && phase == 3) return darkBlueColor;
-
- if (bitval == 5 && phase == 0) return grayColor;
- if (bitval == 10 && phase == 1) return grayColor;
- if (bitval == 5 && phase == 2) return grayColor;
- if (bitval == 10 && phase == 3) return grayColor;
-
- if (bitval == 6 && phase == 0) return blueColor;
- if (bitval == 12 && phase == 1) return blueColor;
- if (bitval == 9 && phase == 2) return blueColor;
- if (bitval == 3 && phase == 3) return blueColor;
-
- if (bitval == 7 && phase == 0) return aquaColor;
- if (bitval == 14 && phase == 1) return aquaColor;
- if (bitval == 13 && phase == 2) return aquaColor;
- if (bitval == 11 && phase == 3) return aquaColor;
-
- if (bitval == 8 && phase == 0) return redColor;
- if (bitval == 1 && phase == 1) return redColor;
- if (bitval == 2 && phase == 2) return redColor;
- if (bitval == 4 && phase == 3) return redColor;
-
- if (bitval == 9 && phase == 0) return orangeColor;
- if (bitval == 3 && phase == 1) return orangeColor;
- if (bitval == 6 && phase == 2) return orangeColor;
- if (bitval == 12 && phase == 3) return orangeColor;
-
- if (bitval == 10 && phase == 0) return gray2Color;
- if (bitval == 5 && phase == 1) return gray2Color;
- if (bitval == 10 && phase == 2) return gray2Color;
- if (bitval == 5 && phase == 3) return gray2Color;
-
- if (bitval == 11 && phase == 0) return yellowColor;
- if (bitval == 7 && phase == 1) return yellowColor;
- if (bitval == 14 && phase == 2) return yellowColor;
- if (bitval == 13 && phase == 3) return yellowColor;
-
- if (bitval == 12 && phase == 0) return purpleColor;
- if (bitval == 9 && phase == 1) return purpleColor;
- if (bitval == 3 && phase == 2) return purpleColor;
- if (bitval == 6 && phase == 3) return purpleColor;
-
- if (bitval == 13 && phase == 0) return pinkColor;
- if (bitval == 11 && phase == 1) return pinkColor;
- if (bitval == 7 && phase == 2) return pinkColor;
- if (bitval == 14 && phase == 3) return pinkColor;
-
- if (bitval == 14 && phase == 0) return lightBlueColor;
- if (bitval == 13 && phase == 1) return lightBlueColor;
- if (bitval == 11 && phase == 2) return lightBlueColor;
- if (bitval == 7 && phase == 3) return lightBlueColor;
-
- return whiteColor;
-
-}
-
-void HiresViewWidget::drawNtscLine(QPainter &painter, int lineNum, QBitArray data) {
- QVector colors;
- colors.resize(data.count()+3);
-
- for (int idx = 0; idx < data.count(); idx++) {
- QBitArray tmp(4);
- tmp[0]=data.at(idx+0);
- if (idx < data.count()-1) tmp[1]=data.at(idx+1); else tmp[1] = false;
- if (idx < data.count()-2) tmp[2]=data.at(idx+2); else tmp[2] = false;
- if (idx < data.count()-3) tmp[3]=data.at(idx+3); else tmp[3] = false;
- colors[idx] = getColorFromBits(tmp,idx %4);
- colors[idx+1] = getColorFromBits(tmp,idx %4);
- colors[idx+2] = getColorFromBits(tmp,idx %4);
- colors[idx+3] = getColorFromBits(tmp,idx %4);
- }
-
-
- for (int idx = 0; idx < colors.count(); idx++)
- {
- painter.setPen(colors.at(idx));
- painter.setBrush(colors.at(idx));
- painter.drawPoint(idx,lineNum);
- }
-}
-
-
-QBitArray HiresViewWidget::byteToBits(quint8 byte) {
- QBitArray bits(8);
- bits.setBit(0,byte & 0x80);
- bits.setBit(7,byte & 0x40);
- bits.setBit(6,byte & 0x20);
- bits.setBit(5,byte & 0x10);
- bits.setBit(4,byte & 0x08);
- bits.setBit(3,byte & 0x04);
- bits.setBit(2,byte & 0x02);
- bits.setBit(1,byte & 0x01);
- return bits;
-}
-
-void HiresViewWidget::setMode(HiresViewWidget::ViewMode viewmode)
-{
- m_viewMode = viewmode;
- update();
-}
-
-int HiresViewWidget::findRowCol(int offset) {
- int retval = 0;
- retval = (*m_rowTable)[offset];
- return retval;
-}
-
-void HiresViewWidget::makeOffsetTable() {
- m_rowTable = new QMap();
-
- for (int idx = 0; idx < 8192; idx++)
- {
- (*m_rowTable)[idx] = -1; // Fill the memory holes. Brute force, but it works.
- }
-
- int count = 0;
-
- int outer = 0x0000;
- for (int idx = 0; idx < 8; idx++) {
- int inner = 0x0000;
- for (int jdx = 0; jdx < 8; jdx++) {
- for (int kdx = 0; kdx<40;kdx++) {
- (*m_rowTable)[outer+inner+kdx] = count + (kdx*10000);
- }
- count++;
- inner += 0x0400;
- }
- outer += 0x0080;
- }
-
-
- outer = 0x0028;
- for (int idx = 0; idx < 8; idx++) {
- int inner = 0x0000;
- for (int jdx = 0; jdx < 8; jdx++) {
- for (int kdx = 0; kdx<40;kdx++) {
- (*m_rowTable)[outer+inner+kdx] = count + (kdx*10000);
- }
- count++;
- inner += 0x0400;
- }
- outer += 0x0080;
- }
-
- outer = 0x0050;
- for (int idx = 0; idx < 8; idx++) {
- int inner = 0x0000;
- for (int jdx = 0; jdx < 8; jdx++) {
- for (int kdx = 0; kdx<40;kdx++) {
- (*m_rowTable)[outer+inner+kdx] = count + (kdx*10000);
- }
- count++;
- inner += 0x0400;
- }
- outer += 0x0080;
- }
-}
-
-void HiresViewWidget::contextMenuEvent(QContextMenuEvent *event) {
- QMenu menu(this);
- menu.addAction(monochromeAction);
- menu.addAction(ntscAction);
- menu.addAction(perPixelColorAction);
- menu.addSeparator();
- menu.addAction(showScanLinesAction);
- menu.exec(event->globalPos());
-}
bool HiresViewWidget::optionsMenuItems(QMenu *menu)
{
- menu->addAction(monochromeAction);
- menu->addAction(ntscAction);
- menu->addAction(perPixelColorAction);
+ menu->addAction(hrsw->monochromeAction());
+ menu->addAction(hrsw->ntscAction());
+ menu->addAction(hrsw->perPixelColorAction());
menu->addSeparator();
- menu->addAction(showScanLinesAction);
+ menu->addAction(hrsw->showScanLinesAction());
return true;
}
@@ -543,5 +52,3 @@ void HiresViewWidget::setFile(GenericFile *file)
}
}
-QMap *HiresViewWidget::m_rowTable = 0;
-
diff --git a/src/ui/viewers/hiresviewwidget.h b/src/ui/viewers/hiresviewwidget.h
index 4f0ce20..72eec19 100644
--- a/src/ui/viewers/hiresviewwidget.h
+++ b/src/ui/viewers/hiresviewwidget.h
@@ -3,6 +3,7 @@
#include "binaryfile.h"
#include "fileviewerinterface.h"
+#include "HiresScreenWidget.h"
#include
#include
@@ -13,22 +14,6 @@
#include
#include
-static const QColor blackColor = QColor(0,0,0);
-static const QColor brownColor = QColor();
-static const QColor darkGreenColor = QColor(96,114,3);
-static const QColor greenColor = QColor(20,245,60);
-static const QColor darkBlueColor = QColor(96,78,189);
-static const QColor grayColor = QColor(156,156,156);
-static const QColor blueColor = QColor(20,207,253);
-static const QColor aquaColor = QColor(114,255,208);
-static const QColor redColor = QColor(227,30,96);
-static const QColor orangeColor = QColor(255,106,60);
-static const QColor gray2Color = QColor(156,156,156);
-static const QColor yellowColor = QColor(208,221,141);
-static const QColor purpleColor = QColor(255,68,253);
-static const QColor pinkColor = QColor(255,160,208);
-static const QColor lightBlueColor = QColor(208,195,255);
-static const QColor whiteColor = QColor(255,255,255);
class HiresViewWidget : public FileViewerInterface
@@ -36,64 +21,15 @@ class HiresViewWidget : public FileViewerInterface
Q_OBJECT
public:
-
- enum ViewMode {
- Monochrome,
- Color1,
- Color2
- };
-
- explicit HiresViewWidget(QWidget *parent = 0);
- void paintEvent(QPaintEvent *event);
-
- void resizeEvent(QResizeEvent *event);
-
- static QBitArray byteToBits(quint8 byte);
- void contextMenuEvent(QContextMenuEvent *);
-
- virtual bool optionsMenuItems(QMenu *);
-
-signals:
+ explicit HiresViewWidget(QWidget *parent = 0);
+ virtual bool optionsMenuItems(QMenu *);
public slots:
void setFile(GenericFile *file);
void setFile(BinaryFile *file);
- void setData(QByteArray data);
- void setMode(ViewMode);
-
-protected slots:
- void handleNtscAction(bool toggled);
- void handleMonochromeAction(bool toggled);
- void handlePerPixelColorAction(bool toggled);
- void handleShowScanLinesAction(bool toggled);
-
private:
- QPixmap m_pixmap;
- QByteArray m_data;
-
-
- int findRowCol(int offset);
- static QMap *m_rowTable;
-
- void makeOffsetTable();
-
- ViewMode m_viewMode;
-
- void drawNtscLine(QPainter &painter,int linenum, QBitArray data);
- void drawMonoLine(QPainter &painter, int lineNum, QBitArray data);
-
- QColor getColorFromBits(QBitArray bits, quint8 phase);
-
- QAction *monochromeAction;
- QAction *ntscAction;
- QAction *perPixelColorAction;
- QAction *showScanLinesAction;
- QActionGroup *formatGroup;
-
- bool m_showScanLines;
-
- void drawPixmap();
+ HiresScreenWidget *hrsw;
BinaryFile *m_file;
};
diff --git a/src/ui/widgets/CharacterSetExplorer.cpp b/src/ui/widgets/CharacterSetExplorer.cpp
new file mode 100644
index 0000000..52fcffe
--- /dev/null
+++ b/src/ui/widgets/CharacterSetExplorer.cpp
@@ -0,0 +1,14 @@
+#include "CharacterSetExplorer.h"
+#include "ui_CharacterSetExplorer.h"
+
+CharacterSetExplorer::CharacterSetExplorer(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::CharacterSetExplorer)
+{
+ ui->setupUi(this);
+}
+
+CharacterSetExplorer::~CharacterSetExplorer()
+{
+ delete ui;
+}
diff --git a/src/ui/widgets/CharacterSetExplorer.h b/src/ui/widgets/CharacterSetExplorer.h
new file mode 100644
index 0000000..4b52663
--- /dev/null
+++ b/src/ui/widgets/CharacterSetExplorer.h
@@ -0,0 +1,22 @@
+#ifndef CHARACTERSETEXPLORER_H
+#define CHARACTERSETEXPLORER_H
+
+#include
+
+namespace Ui {
+class CharacterSetExplorer;
+}
+
+class CharacterSetExplorer : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit CharacterSetExplorer(QWidget *parent = 0);
+ ~CharacterSetExplorer();
+
+private:
+ Ui::CharacterSetExplorer *ui;
+};
+
+#endif // CHARACTERSETEXPLORER_H
diff --git a/src/ui/widgets/CharacterSetExplorer.ui b/src/ui/widgets/CharacterSetExplorer.ui
new file mode 100644
index 0000000..527f891
--- /dev/null
+++ b/src/ui/widgets/CharacterSetExplorer.ui
@@ -0,0 +1,45 @@
+
+
+ CharacterSetExplorer
+
+
+
+ 0
+ 0
+ 423
+ 352
+
+
+
+ Dialog
+
+
+ -
+
+
+ -
+
+
-
+
+
+ Text:
+
+
+
+ -
+
+
+ -
+
+
+ Draw
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ui/widgets/HiresScreenWidget.cpp b/src/ui/widgets/HiresScreenWidget.cpp
new file mode 100644
index 0000000..d3cd799
--- /dev/null
+++ b/src/ui/widgets/HiresScreenWidget.cpp
@@ -0,0 +1,518 @@
+#include "HiresScreenWidget.h"
+
+#include "binaryfile.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include "util.h"
+
+#include
+
+
+HiresScreenWidget::HiresScreenWidget(QWidget *parent) :
+ QWidget(parent)
+{
+ if (m_rawAddressToColRowList.size() == 0 ||
+ m_appleAddressToColRowList.size() == 0)
+ {
+ makeAddressTables();
+ }
+
+ resize(561,384);
+ QSettings settings;
+ m_viewMode = static_cast(settings.value("HiresScreenWidget.ViewMode",NTSCColor).toInt());
+ m_showScanLines = settings.value("HiresScreenWidget.ShowScanLines",true).toBool();
+
+ m_pixmap = QPixmap(561,384);
+ QPainter painter(&m_pixmap);
+ painter.setBrush(Qt::black);
+ painter.drawRect(0,0,this->width(),this->height());
+
+ formatGroup = new QActionGroup(this);
+
+ m_monochromeAction = new QAction("Monochrome Display",this);
+ m_monochromeAction->setCheckable(true);
+ m_monochromeAction->setChecked((m_viewMode == Monochrome));
+ formatGroup->addAction(m_monochromeAction);
+
+ m_ntscAction = new QAction("NTSC Display",this);
+ m_ntscAction->setCheckable(true);
+ m_ntscAction->setChecked((m_viewMode == NTSCColor));
+ formatGroup->addAction(m_ntscAction);
+
+ m_perPixelColorAction= new QAction("Per-Pixel Color Display",this);
+ m_perPixelColorAction->setCheckable(true);
+ m_perPixelColorAction->setChecked((m_viewMode == PerPixelColor));
+ formatGroup->addAction(m_perPixelColorAction);
+
+ m_showScanLinesAction = new QAction("Show Scan Lines",this);
+ m_showScanLinesAction->setCheckable(true);
+ m_showScanLinesAction->setChecked(m_showScanLines);
+
+
+ connect(m_ntscAction, SIGNAL(toggled(bool)), this, SLOT(handleNtscAction(bool)));
+ connect(m_monochromeAction, SIGNAL(toggled(bool)), this, SLOT(handleMonochromeAction(bool)));
+ connect(m_perPixelColorAction, SIGNAL(toggled(bool)), this, SLOT(handlePerPixelColorAction(bool)));
+
+ connect(m_showScanLinesAction, SIGNAL(toggled(bool)), this, SLOT(handleShowScanLinesAction(bool)));
+
+}
+
+void HiresScreenWidget::handleNtscAction(bool toggled) {
+ if (toggled) {
+ m_viewMode = NTSCColor;
+ update();
+ }
+ QSettings settings;
+ settings.setValue("HiresScreenWidget.ViewMode",m_viewMode);
+}
+
+void HiresScreenWidget::handleMonochromeAction(bool toggled) {
+ if (toggled) {
+ m_viewMode = Monochrome;
+ update();
+ }
+ QSettings settings;
+ settings.setValue("HiresScreenWidget.ViewMode",m_viewMode);
+}
+
+void HiresScreenWidget::handlePerPixelColorAction(bool toggled) {
+ if (toggled) {
+ m_viewMode = PerPixelColor;
+ update();
+ }
+ QSettings settings;
+ settings.setValue("HiresScreenWidget.ViewMode",m_viewMode);
+}
+
+void HiresScreenWidget::handleShowScanLinesAction(bool toggled) {
+ m_showScanLines = toggled;
+ update();
+ QSettings settings;
+ settings.setValue("HiresScreenWidget.ShowScanLines",toggled);
+}
+
+
+void HiresScreenWidget::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+
+ // if (m_pixmap.size() != this->size()) {
+ // m_pixmap = m_pixmap.scaled(this->size(),Qt::KeepAspectRatio);
+ // }
+
+ drawPixmap();
+
+ QPainter painter(this);
+
+ QPixmap tmppixmap = m_pixmap;
+ // tmppixmap = tmppixmap.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+
+ painter.drawPixmap(0,0,tmppixmap);
+}
+
+void HiresScreenWidget::resizeEvent(QResizeEvent *)
+{
+
+}
+
+void HiresScreenWidget::drawPixmap() {
+
+ QPainter pmpainter(&m_pixmap);
+
+ pmpainter.setBrush(Qt::black);
+ pmpainter.setPen(Qt::black);
+ pmpainter.drawRect(0,0,m_pixmap.width(),m_pixmap.height());
+
+ if (m_viewMode == Monochrome || m_viewMode == NTSCColor)
+ {
+ pmpainter.setPen(Qt::white);
+ pmpainter.setBrush(Qt::white);
+
+ quint8 chunkCount = 0;
+
+ int idx = 0;
+ while (idx < qMin(m_data.size(),8192)) {
+ ColRow cr = getColRowFromAppleAddress(idx);
+
+ int yoff = cr.row();
+
+ QBitArray bits(561,false);
+ int bitoffset = 0;
+ bool lastbit = false;
+
+ for (int jdx = 0; jdx < 40; jdx++)
+ {
+
+ quint8 byte = m_data[idx++];
+ QBitArray dataBits = byteToBits(byte);
+
+ bool highBit = dataBits.at(0);
+
+ if (highBit) {
+ bits[bitoffset++] = lastbit;
+ }
+
+ for (int xdx = 1; xdx < 7; xdx++) {
+ bits[bitoffset++] = dataBits.at(xdx);
+ bits[bitoffset++] = dataBits.at(xdx);
+ }
+ lastbit = dataBits.at(7);
+ bits[bitoffset++] = dataBits.at(7);
+ if (!highBit) {
+ bits[bitoffset++] = dataBits.at(7);
+ }
+
+
+ }
+
+ if (m_viewMode == Monochrome)
+ {
+ drawMonoLine(pmpainter, yoff*2, bits);
+ if (!m_showScanLines) drawMonoLine(pmpainter, yoff*2+1, bits);
+ }
+ else
+ {
+ drawNtscLine(pmpainter, yoff*2, bits);
+ if (!m_showScanLines) drawNtscLine(pmpainter, yoff*2+1, bits);
+ }
+
+ chunkCount++;
+ if (chunkCount == 3) {
+ chunkCount = 0;
+ idx+=8; // Skip screen hole
+ }
+
+ }
+ }
+ else if (m_viewMode == PerPixelColor)
+ {
+ pmpainter.setPen(Qt::white);
+ pmpainter.setBrush(Qt::white);
+
+ for (int idx = 0; idx < qMin(m_data.size(),8192) ; idx++) {
+ ColRow cr = getColRowFromAppleAddress(idx);
+
+ quint8 byte = m_data[idx];
+
+ bool highBit = byte & 0x80;
+
+ QColor oddColor = highBit? QColor(orangeColor) : QColor(greenColor);
+ QColor evenColor = highBit? QColor(blueColor) : QColor(purpleColor);
+
+ int xoff = cr.col() * 7;
+ int yoff = cr.row() * 2;
+
+ quint8 cOffset = 0;// highBit?1:0;
+
+ quint8 doubleScan = 0;
+ if (!m_showScanLines)
+ {
+ doubleScan = 1;
+ }
+
+ pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
+ pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
+
+ if (byte & 0x01) { pmpainter.drawRect((cOffset+xoff*2)+0,yoff,1,doubleScan); }
+
+ pmpainter.setPen(xoff & 0x01?evenColor:oddColor);
+ pmpainter.setBrush(xoff & 0x01?evenColor:oddColor);
+
+ if (byte & 0x02) { pmpainter.drawRect((cOffset+xoff*2)+2,yoff,1,doubleScan); }
+
+ pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
+ pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
+
+ if (byte & 0x04) { pmpainter.drawRect((cOffset+xoff*2)+4,yoff,1,doubleScan); }
+
+ pmpainter.setPen(xoff & 0x01?evenColor:oddColor);
+ pmpainter.setBrush(xoff & 0x01?evenColor:oddColor);
+
+ if (byte & 0x08) { pmpainter.drawRect((cOffset+xoff*2)+6,yoff,1,doubleScan); }
+
+ pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
+ pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
+
+
+ if (byte & 0x10) { pmpainter.drawRect((cOffset+xoff*2)+8,yoff,1,doubleScan); }
+
+ pmpainter.setPen(xoff & 0x01?evenColor:oddColor);
+ pmpainter.setBrush(xoff & 0x01?evenColor:oddColor);
+
+ if (byte & 0x20) { pmpainter.drawRect((cOffset+xoff*2)+10,yoff,1,doubleScan); }
+
+ pmpainter.setPen(xoff & 0x01?oddColor:evenColor);
+ pmpainter.setBrush(xoff & 0x01?oddColor:evenColor);
+
+
+ if (byte & 0x40) { pmpainter.drawRect((cOffset+xoff*2)+12,yoff,cOffset?0:1,doubleScan); }
+
+
+
+ if (idx >= (280*192)) break;
+ }
+
+ }
+
+}
+
+void HiresScreenWidget::setUnpackedData(QByteArray unpackedData)
+{
+ QByteArray packedData = packData(unpackedData);
+ setData(packedData);
+}
+
+QByteArray HiresScreenWidget::packData(QByteArray unpackedData)
+{
+ QByteArray packedData;
+ packedData.resize(8192);
+ packedData.fill(0x00);
+
+ for (int idx = 0; idx < qMin(unpackedData.count(),8192); idx++)
+ {
+ ColRow cr = getColRowFromRawAddress(idx);
+ packedData[cr.appleAddress()] = unpackedData[idx];
+ }
+
+ return packedData;
+}
+
+int HiresScreenWidget::getLineAddressOffset(int line)
+{
+ static QList blockOffset {
+ 0x0000, 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
+ 0x0028, 0x00A0, 0x0128, 0x01A8, 0x0228, 0x02A8, 0x0328, 0x03A8,
+ 0x0040, 0x00D0, 0x0150, 0x00D0, 0x0250, 0x02D0, 0x0350, 0x03D0
+ };
+
+ static QList boxSub {
+ 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00
+ };
+
+ int block = line / 8;
+ int sub = line % 8;
+
+ return blockOffset[block] + boxSub[sub];
+}
+
+void HiresScreenWidget::setData(QByteArray data) {
+ m_data = data;
+
+ drawPixmap();
+}
+
+void HiresScreenWidget::drawMonoLine(QPainter &painter, int lineNum, QBitArray data) {
+ for (int idx = 0; idx < data.count(); idx++) {
+
+ if (data.at(idx))
+ {
+ painter.setPen(Qt::white);
+ } else {
+ painter.setPen(Qt::black);
+ }
+
+ painter.drawPoint(idx,lineNum);
+ }
+}
+
+QColor HiresScreenWidget::getColorFromBits(QBitArray bits, quint8 phase)
+{
+ quint8 bitval = (bits[0] * 0x08) +
+ (bits[1] * 0x04) +
+ (bits[2] * 0x02) +
+ (bits[3] * 0x01);
+
+ phase %= 4;
+
+ if (bitval == 0) { return blackColor; }
+
+ if (bitval == 1 && phase == 0) return brownColor;
+ if (bitval == 2 && phase == 1) return brownColor;
+ if (bitval == 4 && phase == 2) return brownColor;
+ if (bitval == 8 && phase == 3) return brownColor;
+
+ if (bitval == 2 && phase == 0) return darkGreenColor;
+ if (bitval == 4 && phase == 1) return darkGreenColor;
+ if (bitval == 8 && phase == 2) return darkGreenColor;
+ if (bitval == 1 && phase == 3) return darkGreenColor;
+
+ if (bitval == 3 && phase == 0) return greenColor;
+ if (bitval == 6 && phase == 1) return greenColor;
+ if (bitval == 12 && phase == 2) return greenColor;
+ if (bitval == 9 && phase == 3) return greenColor;
+
+ if (bitval == 4 && phase == 0) return darkBlueColor;
+ if (bitval == 8 && phase == 1) return darkBlueColor;
+ if (bitval == 1 && phase == 2) return darkBlueColor;
+ if (bitval == 2 && phase == 3) return darkBlueColor;
+
+ if (bitval == 5 && phase == 0) return grayColor;
+ if (bitval == 10 && phase == 1) return grayColor;
+ if (bitval == 5 && phase == 2) return grayColor;
+ if (bitval == 10 && phase == 3) return grayColor;
+
+ if (bitval == 6 && phase == 0) return blueColor;
+ if (bitval == 12 && phase == 1) return blueColor;
+ if (bitval == 9 && phase == 2) return blueColor;
+ if (bitval == 3 && phase == 3) return blueColor;
+
+ if (bitval == 7 && phase == 0) return aquaColor;
+ if (bitval == 14 && phase == 1) return aquaColor;
+ if (bitval == 13 && phase == 2) return aquaColor;
+ if (bitval == 11 && phase == 3) return aquaColor;
+
+ if (bitval == 8 && phase == 0) return redColor;
+ if (bitval == 1 && phase == 1) return redColor;
+ if (bitval == 2 && phase == 2) return redColor;
+ if (bitval == 4 && phase == 3) return redColor;
+
+ if (bitval == 9 && phase == 0) return orangeColor;
+ if (bitval == 3 && phase == 1) return orangeColor;
+ if (bitval == 6 && phase == 2) return orangeColor;
+ if (bitval == 12 && phase == 3) return orangeColor;
+
+ if (bitval == 10 && phase == 0) return gray2Color;
+ if (bitval == 5 && phase == 1) return gray2Color;
+ if (bitval == 10 && phase == 2) return gray2Color;
+ if (bitval == 5 && phase == 3) return gray2Color;
+
+ if (bitval == 11 && phase == 0) return yellowColor;
+ if (bitval == 7 && phase == 1) return yellowColor;
+ if (bitval == 14 && phase == 2) return yellowColor;
+ if (bitval == 13 && phase == 3) return yellowColor;
+
+ if (bitval == 12 && phase == 0) return purpleColor;
+ if (bitval == 9 && phase == 1) return purpleColor;
+ if (bitval == 3 && phase == 2) return purpleColor;
+ if (bitval == 6 && phase == 3) return purpleColor;
+
+ if (bitval == 13 && phase == 0) return pinkColor;
+ if (bitval == 11 && phase == 1) return pinkColor;
+ if (bitval == 7 && phase == 2) return pinkColor;
+ if (bitval == 14 && phase == 3) return pinkColor;
+
+ if (bitval == 14 && phase == 0) return lightBlueColor;
+ if (bitval == 13 && phase == 1) return lightBlueColor;
+ if (bitval == 11 && phase == 2) return lightBlueColor;
+ if (bitval == 7 && phase == 3) return lightBlueColor;
+
+ return whiteColor;
+
+}
+
+void HiresScreenWidget::drawNtscLine(QPainter &painter, int lineNum, QBitArray data) {
+ QVector colors;
+ colors.resize(data.count()+3);
+
+ for (int idx = 0; idx < data.count(); idx++) {
+ QBitArray tmp(4);
+ tmp[0]=data.at(idx+0);
+ if (idx < data.count()-1) tmp[1]=data.at(idx+1); else tmp[1] = false;
+ if (idx < data.count()-2) tmp[2]=data.at(idx+2); else tmp[2] = false;
+ if (idx < data.count()-3) tmp[3]=data.at(idx+3); else tmp[3] = false;
+ colors[idx] = getColorFromBits(tmp,idx %4);
+ colors[idx+1] = getColorFromBits(tmp,idx %4);
+ colors[idx+2] = getColorFromBits(tmp,idx %4);
+ colors[idx+3] = getColorFromBits(tmp,idx %4);
+ }
+
+ for (int idx = 0; idx < colors.count(); idx++)
+ {
+ painter.setPen(colors.at(idx));
+ painter.setBrush(colors.at(idx));
+ painter.drawPoint(idx,lineNum);
+ }
+}
+
+
+QBitArray HiresScreenWidget::byteToBits(quint8 byte) {
+ QBitArray bits(8);
+ bits.setBit(0,byte & 0x80);
+ bits.setBit(7,byte & 0x40);
+ bits.setBit(6,byte & 0x20);
+ bits.setBit(5,byte & 0x10);
+ bits.setBit(4,byte & 0x08);
+ bits.setBit(3,byte & 0x04);
+ bits.setBit(2,byte & 0x02);
+ bits.setBit(1,byte & 0x01);
+ return bits;
+}
+
+void HiresScreenWidget::setMode(HiresScreenWidget::ViewMode viewmode)
+{
+ m_viewMode = viewmode;
+ update();
+}
+
+void HiresScreenWidget::contextMenuEvent(QContextMenuEvent *event) {
+ QMenu menu(this);
+ menu.addAction(m_monochromeAction);
+ menu.addAction(m_ntscAction);
+ menu.addAction(m_perPixelColorAction);
+ menu.addSeparator();
+ menu.addAction(m_showScanLinesAction);
+ menu.exec(event->globalPos());
+}
+
+HiresScreenWidget::ColRow HiresScreenWidget::getColRowFromAppleAddress(quint16 address)
+{
+ if (address > 8191) {
+ qDebug() << "Invalid apple address " << address;
+ address = 8191;
+ }
+ return m_appleAddressToColRowList[address];
+}
+
+HiresScreenWidget::ColRow HiresScreenWidget::getColRowFromRawAddress(quint16 address)
+{
+ if (address > 8191) {
+ qDebug() << "Invalid raw address " << address;
+ address = 8191;
+ }
+ return m_rawAddressToColRowList[address];
+}
+
+void HiresScreenWidget::makeAddressTables()
+{
+ qDebug() << " ****** makeAddressTables()";
+ m_rawAddressToColRowList.resize(8192);
+ m_appleAddressToColRowList.resize(8192);
+
+ for (int row = 0; row < 192; row++)
+ {
+ for (int col = 0; col < 40; col++)
+ {
+ ColRow cr(col,row);
+ // qDebug() << "Col: " << col << "Row: " << row << "Raw: " << cr.rawAddress() << " Apple: " << cr.appleAddress();
+
+ m_rawAddressToColRowList[cr.rawAddress()] = cr;
+ m_appleAddressToColRowList[cr.appleAddress()] = cr;
+ }
+ }
+
+#ifdef DEBUGHOLES
+ int num = 0;
+ quint16 lasthole = 0;
+ for (int idx = 0; idx < 8192; idx++)
+ {
+ if (!m_appleAddressToColRowList[idx].isDefined())
+ {
+ if (lasthole != 0 && lasthole != (idx-1)) { qDebug() << "\n"; }
+ qDebug() << "Hole" << num << "at" << idx+0x2000 << uint16ToHex(idx+0x2000); ;
+ num++;
+ lasthole = idx;
+ }
+ }
+#endif
+}
+
+
+QVector HiresScreenWidget::m_rawAddressToColRowList
+= QVector();
+QVector HiresScreenWidget::m_appleAddressToColRowList
+= QVector();
diff --git a/src/ui/widgets/HiresScreenWidget.h b/src/ui/widgets/HiresScreenWidget.h
new file mode 100644
index 0000000..c6d9940
--- /dev/null
+++ b/src/ui/widgets/HiresScreenWidget.h
@@ -0,0 +1,149 @@
+#ifndef HIRESSCREENWIDGET_H
+#define HIRESSCREENWIDGET_H
+
+#include "binaryfile.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static const QColor blackColor = QColor(0,0,0);
+static const QColor grayColor = QColor(156,156,156);
+static const QColor gray2Color = QColor(156,156,156);
+static const QColor whiteColor = QColor(255,255,255);
+static const QColor darkBlueColor = QColor(96,78,189);
+static const QColor lightBlueColor = QColor(208,195,255);
+static const QColor purpleColor = QColor(255,68,253);
+static const QColor redColor = QColor(227,30,96);
+static const QColor pinkColor = QColor(255,160,208);
+static const QColor orangeColor = QColor(255,106,60);
+static const QColor brownColor = QColor(96,114,3);
+static const QColor yellowColor = QColor(208,221,141);
+static const QColor greenColor = QColor(20,245,60);
+static const QColor darkGreenColor = QColor(0,163,96);
+static const QColor aquaColor = QColor(114,255,208);
+static const QColor blueColor = QColor(20,207,253);
+
+class HiresScreenWidget : public QWidget
+{
+ Q_OBJECT
+public:
+
+ class ColRow {
+ public:
+ ColRow() { m_col = 0; m_row = 0; m_undefined = true; }
+ ColRow(quint8 col, quint8 row) { setColRow(col,row); }
+ void setColRow(quint8 col, quint8 row) { m_col = col; m_row = row; calc(); }
+
+ quint8 col() const { return m_col; }
+ quint8 row() const { return m_row; }
+
+ bool isDefined() const { return !m_undefined; }
+ bool isUndefined() const { return m_undefined; }
+
+ quint16 appleAddress() { return m_appleAddress; }
+ quint16 rawAddress() { return m_rawAddress; }
+
+ private:
+ quint8 m_col;
+ quint8 m_row;
+
+ quint16 m_appleAddress;
+ quint16 m_rawAddress;
+ bool m_undefined;
+
+ void calc() {
+ if (m_col > 39) { qDebug() << "Col out of range: " << m_col; m_col = 39; }
+ if (m_row > 191) { qDebug() << "Row out of range: " << m_row; m_row = 191; }
+
+ m_rawAddress = (m_row*40) + m_col;
+
+ unsigned short blockOffset[] = {
+ 0x0000, 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
+ 0x0028, 0x00A8, 0x0128, 0x01A8, 0x0228, 0x02A8, 0x0328, 0x03A8,
+ 0x0050, 0x00D0, 0x0150, 0x01D0, 0x0250, 0x02D0, 0x0350, 0x03D0
+ };
+
+ unsigned short boxSub[] = {
+ 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, 0x1400, 0x1800, 0x1C00
+ };
+
+ m_appleAddress = blockOffset[m_row/8]+boxSub[m_row%8] + m_col;
+ m_undefined = false;
+ }
+
+ };
+
+ enum ViewMode {
+ Monochrome,
+ PerPixelColor,
+ NTSCColor
+ };
+
+ explicit HiresScreenWidget(QWidget *parent = 0);
+ void paintEvent(QPaintEvent *event);
+
+ void resizeEvent(QResizeEvent *event);
+
+ static QBitArray byteToBits(quint8 byte);
+ void contextMenuEvent(QContextMenuEvent *);
+
+ QAction *monochromeAction() { return m_monochromeAction; }
+ QAction *ntscAction() { return m_ntscAction; }
+ QAction *perPixelColorAction() { return m_perPixelColorAction; }
+ QAction *showScanLinesAction() { return m_showScanLinesAction; }
+
+ ColRow getColRowFromAppleAddress(quint16 address);
+ ColRow getColRowFromRawAddress(quint16 address);
+
+signals:
+
+public slots:
+ void setData(QByteArray data);
+ void setMode(ViewMode);
+ void setUnpackedData(QByteArray unpackedData);
+
+protected:
+ int getLineAddressOffset(int line);
+ QByteArray packData(QByteArray unpackedData);
+
+protected slots:
+ void handleNtscAction(bool toggled);
+ void handleMonochromeAction(bool toggled);
+ void handlePerPixelColorAction(bool toggled);
+ void handleShowScanLinesAction(bool toggled);
+
+private:
+ void makeOffsetTable();
+ void makeAddressTables();
+ QColor getColorFromBits(QBitArray bits, quint8 phase);
+ void drawNtscLine(QPainter &painter,int linenum, QBitArray data);
+ void drawMonoLine(QPainter &painter, int lineNum, QBitArray data);
+ void drawPixmap();
+
+
+ QPixmap m_pixmap;
+ QByteArray m_data;
+
+ ViewMode m_viewMode;
+
+ QAction *m_monochromeAction;
+ QAction *m_ntscAction;
+ QAction *m_perPixelColorAction;
+ QAction *m_showScanLinesAction;
+ QActionGroup *formatGroup;
+
+ bool m_showScanLines;
+
+ static QVector m_rawAddressToColRowList;
+ static QVector m_appleAddressToColRowList;
+};
+
+#endif // HIRESSCREENWIDGET_H