diff --git a/AppleSAWS.pro b/AppleSAWS.pro index b431c52..f322da3 100644 --- a/AppleSAWS.pro +++ b/AppleSAWS.pro @@ -1,5 +1,5 @@ -QT += core gui +QT += core gui CONFIG += c++11 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets @@ -18,6 +18,7 @@ INCLUDEPATH += src/textfile INCLUDEPATH += src/ui/viewers INCLUDEPATH += src/imported INCLUDEPATH += src/internals +INCLUDEPATH += src/ui/widgets/ INCLUDEPATH += src/ui DEFINES += WS_VIDEO @@ -34,22 +35,26 @@ SOURCES += \ src/util/applestring.cxx \ src/applesoftfile/applesoftfile.cxx \ src/applesoftfile/applesofttoken.cxx \ + src/applesoftfile/applesoftformatter.cxx \ + src/applesoftfile/applesoftline.cpp \ src/binaryfile/disassembler.cxx \ src/binaryfile/binaryfile.cxx \ src/textfile/textfile.cxx \ src/ui/catalogwidget.cxx \ src/ui/mainwindow.cxx \ src/ui/viewers/hiresviewwidget.cxx \ - src/ui/viewers/applesoftfileviewer.cxx \ - src/applesoftfile/applesoftformatter.cxx \ - src/applesoftfile/applesoftline.cpp \ - src/internals/memory.cxx \ + src/ui/viewers/applesoftfileviewer.cxx \ src/ui/viewers/disassemblerviewer.cpp \ src/ui/viewers/hexdumpviewer.cpp \ src/ui/viewers/texthexdumpviewer.cpp \ - src/relocatablefile/relocatablefile.cxx \ src/ui/viewers/mazeviewer.cpp \ - src/binaryfile/binaryfilemetadata.cpp + src/ui/viewers/charsetviewer.cpp \ + src/internals/memory.cxx \ + src/relocatablefile/relocatablefile.cxx \ + src/binaryfile/binaryfilemetadata.cpp \ + src/util/charset.cpp \ + src/ui/widgets/characterwidget.cpp + HEADERS += \ src/diskfiles/dos33/diskfile.h \ @@ -78,7 +83,10 @@ HEADERS += \ src/ui/viewers/texthexdumpviewer.h \ src/relocatablefile/relocatablefile.h \ src/ui/viewers/mazeviewer.h \ - src/binaryfile/binaryfilemetadata.h + src/binaryfile/binaryfilemetadata.h \ + src/ui/widgets/characterwidget.h \ + src/util/charset.h \ + src/ui/viewers/charsetviewer.h FORMS += \ src/ui/catalogwidget.ui \ diff --git a/src/ui/mainwindow.cxx b/src/ui/mainwindow.cxx index 5b2b0a4..e707d1b 100644 --- a/src/ui/mainwindow.cxx +++ b/src/ui/mainwindow.cxx @@ -11,7 +11,7 @@ #include "hexdumpviewer.h" #include "mazeviewer.h" #include "texthexdumpviewer.h" - +#include "charsetviewer.h" #include "relocatablefile.h" #include @@ -114,6 +114,13 @@ void MainWindow::openInMazeViewer(BinaryFile *file) { hvwma->setFile(file); } +void MainWindow::openInCharSetViewer(BinaryFile *file) +{ + CharSetViewer *csv = new CharSetViewer(0); + csv->setFile(file); + csv->show(); +} + void MainWindow::openInApplesoftFileViewer(ApplesoftFile *file) { ApplesoftFileViewer *afv = new ApplesoftFileViewer(0); @@ -151,6 +158,10 @@ void MainWindow::handleDiskItemSelectedDefaultOpen(DiskFile *disk, FileDescripti { openInMazeViewer(binfile); } + else if (file->filename().contains(".set",Qt::CaseInsensitive)) + { + openInCharSetViewer(binfile); + } else { openInDisassemblerViewer(binfile); diff --git a/src/ui/mainwindow.h b/src/ui/mainwindow.h index 2908446..d64f218 100644 --- a/src/ui/mainwindow.h +++ b/src/ui/mainwindow.h @@ -43,6 +43,7 @@ protected: void openInHiresViewWidget(BinaryFile *file, QString filename); void openInDisassemblerViewer(BinaryFile *file); void openInMazeViewer(BinaryFile *file); + void openInCharSetViewer(BinaryFile *file); private: Ui::MainWindow *ui; diff --git a/src/ui/viewers/charsetviewer.cpp b/src/ui/viewers/charsetviewer.cpp new file mode 100644 index 0000000..19555b5 --- /dev/null +++ b/src/ui/viewers/charsetviewer.cpp @@ -0,0 +1,40 @@ +#include "charsetviewer.h" + +#include + +CharSetViewer::CharSetViewer(QWidget *parent) : QWidget(parent) +{ + m_file = Q_NULLPTR; + + QString title = QString("Character Set Viewer"); + setWindowTitle(title); +} + +void CharSetViewer::setFile(BinaryFile *file) +{ + m_file = file; + QString title = QString("Character Set Viewer: %1").arg(file->filename()); + setWindowTitle(title); + m_data = file->data(); + m_data.resize(file->length()); + m_charset.buildSetFromSetBlob(m_data); + + int xpos = 0; + int ypos = 0; + foreach (CharSetCharacter csc, m_charset.allCharacters()) + { + qDebug() << "CSC: " << csc.asciiVal(); + CharacterWidget *cw = new CharacterWidget(this,csc,4); + cw->showGrid(true); + cw->enableBitShift(true); + cw->setBgColor(Qt::white); + cw->setFgColor(Qt::black); + cw->move(xpos,ypos); + cw->show(); + xpos+= cw->width(); + if (xpos/cw->width() > 11) { + xpos = 0; + ypos += cw->height(); + } + } +} diff --git a/src/ui/viewers/charsetviewer.h b/src/ui/viewers/charsetviewer.h new file mode 100644 index 0000000..e9c23ee --- /dev/null +++ b/src/ui/viewers/charsetviewer.h @@ -0,0 +1,28 @@ +#ifndef CHARSETVIEWER_H +#define CHARSETVIEWER_H + +#include "binaryfile.h" +#include "characterwidget.h" + +#include + +class CharSetViewer : public QWidget +{ + Q_OBJECT +public: + explicit CharSetViewer(QWidget *parent = 0); + + void setFile(BinaryFile *file); + +signals: + +private: + BinaryFile *m_file; + + QByteArray m_data; + + CharacterSet m_charset; + +}; + +#endif // CHARSETVIEWER_H diff --git a/src/ui/widgets/characterwidget.cpp b/src/ui/widgets/characterwidget.cpp new file mode 100644 index 0000000..c333bd0 --- /dev/null +++ b/src/ui/widgets/characterwidget.cpp @@ -0,0 +1,137 @@ +#include "characterwidget.h" + +#include +#include +#include +#include +#include + +CharacterWidget::CharacterWidget(QWidget *parent, CharSetCharacter ch, int scale) + : QWidget(parent), m_character(ch), m_scale(scale) +{ + resize(15*m_scale, 16*m_scale); + setMaximumSize(this->size()); + setMinimumSize(this->size()); + m_pixmap = QPixmap(this->size()); + setFgColor(Qt::black); + setBgColor(Qt::white); + setGridColor(Qt::red); + QString name = QChar(ch.asciiVal()); + if (ch.asciiVal() == ' ') { name = ""; } + if (ch.asciiVal() == 0x7f) { name = ""; } + QString ttstring = QString("Ascii: %1\nCharacter: %2").arg(ch.asciiVal()).arg(name); + setToolTip(ttstring); + doRepaint(); +} + +void CharacterWidget::doRepaint() +{ + qDebug() << "doRepaint() begin"; + m_pixmap.fill(m_bgcolor); + QPainter painter(&m_pixmap); + + painter.setPen(m_fgcolor); + painter.setBrush(m_fgcolor); + + QByteArray chardata = m_character.data(); + qDebug() << chardata; + + for (quint8 yval = 0; yval < 8; yval++) + { + int ypos = yval * m_scale*2; + + quint8 line = chardata[yval]; + + QBitArray bits(7); + bits.setBit(0,(line & 0x01)); + bits.setBit(1,(line & 0x02)); + bits.setBit(2,(line & 0x04)); + bits.setBit(3,(line & 0x08)); + bits.setBit(4,(line & 0x10)); + bits.setBit(5,(line & 0x20)); + bits.setBit(6,(line & 0x40)); + + qDebug() << "Bits: " << bits; + int shiftval = 0; + painter.setBrush(m_fgcolor); + if (m_dobitshift && (line & 0x80)) { + shiftval = 1; + painter.setBrush(Qt::gray); + } + + for (int jdx = 0; jdx < 7; jdx++) + { + if (bits.testBit(jdx)) + { + painter.drawRect((jdx*2+shiftval)*m_scale, ypos, + m_scale*2, m_scale*2); + } + } + + } + + if (m_showgrid) + { + painter.setPen(QPen(m_gridcolor,1,Qt::DotLine)); + painter.setBrush(Qt::NoBrush); + for (int idx = 0; idx < 8; idx++) + { + painter.drawLine(0, idx*m_scale*2, m_pixmap.width(), idx*m_scale*2); + } + for (int idx = 0; idx < 9; idx++) + { + painter.drawLine(idx*m_scale*2, 0, idx*m_scale*2, m_pixmap.width()); + } + painter.setPen(QPen(m_gridcolor,2,Qt::SolidLine)); + painter.drawLine(0,0, 0,m_pixmap.height()); + painter.drawLine(0,m_pixmap.height(), m_pixmap.width(), m_pixmap.height()); + painter.drawLine(m_pixmap.width(), m_pixmap.height(), m_pixmap.width(),0); + painter.drawLine(m_pixmap.width(),0, 0,0); + + } + + repaint(); + qDebug() << "end"; +} + +void CharacterWidget::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.drawPixmap(0,0,m_pixmap); +} + +void CharacterWidget::resizeEvent(QResizeEvent *event) +{ + m_pixmap = m_pixmap.scaled(event->size().width(),event->size().height()); + doRepaint(); +} + +void CharacterWidget::setFgColor(QColor color) +{ + m_fgcolor = color; + doRepaint(); +} + +void CharacterWidget::setBgColor(QColor color) +{ + m_bgcolor = color; + doRepaint(); +} + +void CharacterWidget::setGridColor(QColor color) +{ + m_gridcolor = color; + doRepaint(); +} + +void CharacterWidget::showGrid(bool show) +{ + m_showgrid = show; + doRepaint(); +} + +void CharacterWidget::enableBitShift(bool enable) +{ + m_dobitshift = enable; + doRepaint(); +} diff --git a/src/ui/widgets/characterwidget.h b/src/ui/widgets/characterwidget.h new file mode 100644 index 0000000..3f2cb40 --- /dev/null +++ b/src/ui/widgets/characterwidget.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include + +#include "charset.h" + +class CharacterWidget : public QWidget +{ + Q_OBJECT + +public: + CharacterWidget(QWidget *parent = 0, + CharSetCharacter ch = CharSetCharacter(), + int scale = 4); + + void doRepaint(); + +protected: + void resizeEvent(QResizeEvent *event); + + void paintEvent(QPaintEvent *); +signals: + +public slots: + void setFgColor(QColor color); + void setBgColor(QColor color); + void setGridColor(QColor color); + + void showGrid(bool show); + void enableBitShift(bool enable); + + +private: + QPixmap m_pixmap; + + QColor m_fgcolor; + QColor m_bgcolor; + QColor m_gridcolor; + bool m_showgrid; + bool m_dobitshift; + + CharSetCharacter m_character; + + int m_scale; +}; + diff --git a/src/util/charset.cpp b/src/util/charset.cpp new file mode 100644 index 0000000..d34e24a --- /dev/null +++ b/src/util/charset.cpp @@ -0,0 +1,57 @@ +#include "charset.h" +#include + + +CharSetCharacter::CharSetCharacter(quint8 asciival, QByteArray bytes) +{ + setAsciiVal(asciival); + setData(bytes); +} + +void CharSetCharacter::setData(QByteArray bytes) +{ + bytes.resize(8); + m_data = bytes; +} + +void CharSetCharacter::setData(quint8 b0, quint8 b1, quint8 b2, quint8 b3, quint8 b4, quint8 b5, quint8 b6, quint8 b7) +{ + QByteArray data; + data.append(b0); + data.append(b1); + data.append(b2); + data.append(b3); + data.append(b4); + data.append(b5); + data.append(b6); + data.append(b7); + + setData(data); +} + +void CharacterSet::buildSetFromSetBlob(QByteArray data) +{ + if (data.size() != 768) { + qWarning("Unexpected character set size: %d (not 768). Resizing.",data.size()); + data.resize(768); + } +qDebug() << "BuildSet: " << data; + int val = 32; + for (int idx = 0; idx < 768; idx+=8) + { + QByteArray ch = data.mid(idx,8); + qDebug() << "Added character " << idx / 8 << "Data: " << ch; + + CharSetCharacter csc = CharSetCharacter(val,ch); + m_charmap.insert(val,csc); + val++; + } +} + +QList CharacterSet::allCharacters() const +{ + qDebug() << "allCharacters: " << m_charmap.values().count(); + return m_charmap.values(); + + +} diff --git a/src/util/charset.h b/src/util/charset.h new file mode 100644 index 0000000..f68dc59 --- /dev/null +++ b/src/util/charset.h @@ -0,0 +1,43 @@ +#ifndef CHARSETCHARACTER_H +#define CHARSETCHARACTER_H + +#include +#include + + + +class CharSetCharacter +{ +public: + CharSetCharacter(quint8 asciival = 0, QByteArray bytes = QByteArray()); + void setAsciiVal(quint8 val) { m_asciival = val; } + quint8 asciiVal() const { return m_asciival; } + + void setData(QByteArray bytes); + void setData(quint8 b0 = 0, quint8 b1 = 0, quint8 b2 = 0, quint8 b3 = 0, + quint8 b4 = 0, quint8 b5 = 0, quint8 b6 = 0, quint8 b7 = 0); + QByteArray data() const { return m_data; } + +private: + quint8 m_asciival; + QByteArray m_data; +}; + + + + +class CharacterSet +{ +public: + void buildSetFromSetBlob(QByteArray data); + CharSetCharacter operator[](int asciival) const { return m_charmap[asciival]; } + QList allCharacters() const; + +private: + QMap m_charmap; +}; + + + + +#endif // CHARSETCHARACTER_H