diff --git a/AppleSAWS.pro b/AppleSAWS.pro index 07afc5b..389045e 100644 --- a/AppleSAWS.pro +++ b/AppleSAWS.pro @@ -40,6 +40,7 @@ SOURCES += \ src/diskfiles/dos33/filedescriptiveentry.cxx \ src/diskfiles/dos33/genericfile.cxx \ src/ui/viewers/intbasicfileviewer.cxx \ + src/ui/widgets/notesdialog.cpp \ src/util/applestring.cxx \ src/applesoftfile/applesoftfile.cxx \ src/applesoftfile/applesofttoken.cxx \ @@ -88,6 +89,7 @@ HEADERS += \ src/diskfiles/dos33/genericfile.h \ src/intbasic/IntBasicFile.h \ src/ui/viewers/intbasicfileviewer.h \ + src/ui/widgets/notesdialog.h \ src/util/util.h \ src/util/applestring.h \ src/applesoftfile/applesoftfile.h \ @@ -146,4 +148,8 @@ FORMS += \ src/ui/widgets/CharacterSetExplorer.ui \ src/ui/widgets/DisassemblerMetadataDialog.ui \ src/ui/widgets/LocationInfoDialog.ui \ - src/ui/widgets/asciiinfodialog.ui + src/ui/widgets/asciiinfodialog.ui \ + src/ui/widgets/notesdialog.ui + +RESOURCES += \ + src/resource/resources.qrc diff --git a/src/intbasic/IntBasicFile.cxx b/src/intbasic/IntBasicFile.cxx index 252606b..d86e500 100644 --- a/src/intbasic/IntBasicFile.cxx +++ b/src/intbasic/IntBasicFile.cxx @@ -148,7 +148,7 @@ QByteArray IntBasicFile::dumpBufferAsIntBasicFile(QByteArray origdata) } data.removeFirst(); - int alen = get16(data[0],data[1]); + // int alen = get16(data[0],data[1]); int position = 2; diff --git a/src/main.cpp b/src/main.cpp index ac9acba..64ab42b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "binaryfile.h" #include "genericfile.h" @@ -15,6 +17,15 @@ int main(int argc, char** argv) QCoreApplication::setOrganizationName("LydianScaleSoftware"); QCoreApplication::setOrganizationDomain("lydianscale.com"); QCoreApplication::setApplicationName("AppleSAWS"); + + qDebug("Adding fonts"); + auto x = QFontDatabase::addApplicationFont(":/fonts/A2_40Col.ttf"); + auto y = QFontDatabase::addApplicationFont(":/fonts/A2_80Col.ttf"); + qDebug("40Col: %d 80Col: %d",x,y); + + qDebug() << "40: " << QFontDatabase::applicationFontFamilies(0); + qDebug() << "80: " << QFontDatabase::applicationFontFamilies(1); + DiskExplorer w; QSettings settings; QString lastOpened = settings.value("lastOpened").toString(); diff --git a/src/resource/FreeLicense.txt b/src/resource/FreeLicense.txt new file mode 100644 index 0000000..09450f2 --- /dev/null +++ b/src/resource/FreeLicense.txt @@ -0,0 +1,20 @@ +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/resource/PRNumber3.ttf b/src/resource/PRNumber3.ttf new file mode 100644 index 0000000..4843041 Binary files /dev/null and b/src/resource/PRNumber3.ttf differ diff --git a/src/resource/PrintChar21.ttf b/src/resource/PrintChar21.ttf new file mode 100644 index 0000000..7204e97 Binary files /dev/null and b/src/resource/PrintChar21.ttf differ diff --git a/src/resource/notes.txt b/src/resource/notes.txt new file mode 100644 index 0000000..ebae99f --- /dev/null +++ b/src/resource/notes.txt @@ -0,0 +1,64 @@ +# AppleSAWS +## Apple Software Analysis WorkShop v.0.0.3pr + +https://github.com/markdavidlong/AppleSAWS + +### Welcome + +This is a toolkit for exploring DOS 3.3 disk contents. I started this because +I had become interested in a game that I used to play a long time ago and I +wanted to dig deeper into the internals of how it worked. Since it was a nice +combination of a series of Applesoft and Binary files, I decided that a tool +to help explore those types of things would be handy. Of course, I've ended +up spending far more time writing the tool than I have actually exploring the +game, but nonetheless, it's been a fun ongoing project. + +*** + +### Legal Stuff: + +I am grateful to be able to include a couple of wonderful Apple II inspired fonts +from KreativeKorp, **Print Char 21** and **PR Number 3** available from +https://www.kreativekorp.com/software/fonts/apple2.shtml + +Accordingly, here is their license: + +``` +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. +``` + +*** + +And, of course, this program is released under the MIT License: + + +``` +The MIT License (MIT) + +Copyright (c) 2015-2021 Mark D. Long + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` diff --git a/src/resource/resources.qrc b/src/resource/resources.qrc new file mode 100644 index 0000000..5758079 --- /dev/null +++ b/src/resource/resources.qrc @@ -0,0 +1,10 @@ + + + FreeLicense.txt + PrintChar21.ttf + PRNumber3.ttf + + + notes.txt + + diff --git a/src/ui/diskexplorer/DiskExplorer.cpp b/src/ui/diskexplorer/DiskExplorer.cpp index 177803d..567fb24 100644 --- a/src/ui/diskexplorer/DiskExplorer.cpp +++ b/src/ui/diskexplorer/DiskExplorer.cpp @@ -14,10 +14,13 @@ DiskExplorer::DiskExplorer(QWidget *parent) : QMainWindow(parent) { - m_action_Unload_Disk_Image = 0; - m_disk = 0; + m_action_Unload_Disk_Image = nullptr; + m_disk = nullptr; m_horizSizePref = -1; m_toolsHidden = true; + m_notesDialog = nullptr; + m_AsciiInfoDialog = nullptr; + m_hrcgDialog = nullptr; resize(300,800); initUi(); @@ -76,10 +79,10 @@ void DiskExplorer::initUi() QAction *action_HRCG_Commands = new QAction(tr("&HRCG Commands..."),this); menu->addAction(action_HRCG_Commands); - m_hrcgDialog = new HRCGControlsInfo(this); + if (!m_hrcgDialog) m_hrcgDialog = new HRCGControlsInfo(this); connect(action_HRCG_Commands, &QAction::triggered, m_hrcgDialog, &HRCGControlsInfo::show); - m_hexConverter = new HexConverter(this); + if (!m_hexConverter) m_hexConverter = new HexConverter(this); connect(action_Hex_Converter, &QAction::triggered, m_hexConverter, &HexConverter::show); QAction *action_Ascii_Info = new QAction(tr("&ASCII Table..."),this); @@ -87,6 +90,12 @@ void DiskExplorer::initUi() m_AsciiInfoDialog = new AsciiInfoDialog(this); connect(action_Ascii_Info, &QAction::triggered, m_AsciiInfoDialog, &AsciiInfoDialog::show); + menu->addSeparator(); + + QAction *action_Notes = new QAction(tr("&Notes..."), this); + menu->addAction(action_Notes); + if (!m_notesDialog) m_notesDialog = new NotesDialog(this); + connect(action_Notes, &QAction::triggered, m_notesDialog, &NotesDialog::show); QWidget *widget = new QWidget(0); m_gridLayout = new QGridLayout(); diff --git a/src/ui/diskexplorer/DiskExplorer.h b/src/ui/diskexplorer/DiskExplorer.h index 1f51cb7..c0fecc8 100644 --- a/src/ui/diskexplorer/DiskExplorer.h +++ b/src/ui/diskexplorer/DiskExplorer.h @@ -11,6 +11,7 @@ #include "hexdumpviewer.h" #include "viewerbase.h" #include "asciiinfodialog.h" +#include "notesdialog.h" #include #include @@ -68,7 +69,7 @@ private: HRCGControlsInfo *m_hrcgDialog; HexConverter *m_hexConverter; AsciiInfoDialog *m_AsciiInfoDialog; - + NotesDialog *m_notesDialog; QAction *m_action_Unload_Disk_Image; diff --git a/src/ui/viewers/applesoftfileviewer.cxx b/src/ui/viewers/applesoftfileviewer.cxx index 840c71b..05ad3c3 100644 --- a/src/ui/viewers/applesoftfileviewer.cxx +++ b/src/ui/viewers/applesoftfileviewer.cxx @@ -18,10 +18,13 @@ ApplesoftFileViewer::ApplesoftFileViewer(QWidget *parent) : m_afdv = Q_NULLPTR; - QFont textAreaFont; - textAreaFont.setStyleHint(QFont::Monospace); + // QFont textAreaFont("PR Number 3"); + QFont textAreaFont("Print Char 21"); + // textAreaFont.setStyleHint(QFont::Monospace); textAreaFont.setPointSize(12); + qDebug() << "************ " << textAreaFont; + QSettings settings; QString title = QString("Applesoft Viewer"); m_title = title; @@ -51,7 +54,8 @@ ApplesoftFileViewer::ApplesoftFileViewer(QWidget *parent) : setSyntaxHighlighting(settings.value("ASViewer.syntaxHighlighting",true).toBool(), NoReformat); setShowCtrlChars(settings.value("ASViewer.showCtrlChars",true).toBool(), NoReformat); - setTextFont(fontFromSettings("ASViewer.textFont", textAreaFont), NoReformat); + // setTextFont(fontFromSettings("ASViewer.textFont", textAreaFont), NoReformat); + setTextFont(textAreaFont, NoReformat); } ApplesoftFileViewer::~ApplesoftFileViewer() @@ -168,8 +172,8 @@ bool ApplesoftFileViewer::makeMenuOptions(QMenu *menu) bool ok; QFont font = QFontDialog::getFont(&ok, ui->textArea->font(), - this, "Set Font", - QFontDialog::MonospacedFonts); + this, "Set Font" + /*, QFontDialog::MonospacedFonts| QFontDialog::DontUseNativeDialog */); if (ok) { setTextFont(font,ForceReformat); fontToSettings("ASViewer.textFont",font); diff --git a/src/ui/viewers/intbasicfileviewer.h b/src/ui/viewers/intbasicfileviewer.h index addcb17..1d1be22 100644 --- a/src/ui/viewers/intbasicfileviewer.h +++ b/src/ui/viewers/intbasicfileviewer.h @@ -16,7 +16,7 @@ public: explicit IntBasicFileViewer(QWidget *parent = nullptr); ~IntBasicFileViewer(); - bool optionsMenuItems(QMenu *menu) { return false; } + bool optionsMenuItems(QMenu * /*menu*/) { return false; } public slots: void setFile(GenericFile *file); diff --git a/src/ui/viewers/mazeviewer.cpp b/src/ui/viewers/mazeviewer.cpp index 6d36508..cef55dc 100644 --- a/src/ui/viewers/mazeviewer.cpp +++ b/src/ui/viewers/mazeviewer.cpp @@ -223,11 +223,11 @@ void MazeViewer::drawMaze() quint8 roomPlayerIsIn = mem.at(0x8008 + (32*rdx)); if (roomPlayerIsIn == currentRoom) { - if (rdx == 0) { pl += QString("\u2460"); } - if (rdx == 1) { pl += QString("\u2461"); } - if (rdx == 2) { pl += QString("\u2462"); } - if (rdx == 3) { pl += QString("\u2463"); } - if (rdx == 4) { pl += QString("\u2464"); } + if (rdx == 0) { pl += QString(u8"\u2460"); } + if (rdx == 1) { pl += QString(u8"\u2461"); } + if (rdx == 2) { pl += QString(u8"\u2462"); } + if (rdx == 3) { pl += QString(u8"\u2463"); } + if (rdx == 4) { pl += QString(u8"\u2464"); } } } diff --git a/src/ui/widgets/FlowLineTextBrowser.cpp b/src/ui/widgets/FlowLineTextBrowser.cpp index bfa252f..27d0102 100644 --- a/src/ui/widgets/FlowLineTextBrowser.cpp +++ b/src/ui/widgets/FlowLineTextBrowser.cpp @@ -267,6 +267,7 @@ int FlowLineTextBrowser::getChannelOffset(int channel) return width - (channel * 9)- 10; } + int FlowLineTextBrowser::lineAreaWidth() { if (!m_jl) return 10; diff --git a/src/ui/widgets/FlowLineTextBrowser.h b/src/ui/widgets/FlowLineTextBrowser.h index 995e0bd..4263ff9 100644 --- a/src/ui/widgets/FlowLineTextBrowser.h +++ b/src/ui/widgets/FlowLineTextBrowser.h @@ -12,11 +12,12 @@ #include #include #include +#include -class LineArea; class FlowLineTextBrowser : public QTextBrowser { + class LineArea; public: FlowLineTextBrowser(QWidget *parent = Q_NULLPTR); @@ -37,8 +38,6 @@ protected: bool isBlockVisible(QTextBlock block) const; void showEvent(QShowEvent *) Q_DECL_OVERRIDE; - // void wheelEvent(QWheelEvent *ev) Q_DECL_OVERRIDE { if (ev) { ev->ignore(); } } - private slots: void updateLineAreaWidth(); void updateLineArea(const QRect &, int); @@ -47,16 +46,17 @@ public slots: void setLineAreaVisible(bool visible); private: - LineArea *m_lineArea; + FlowLineTextBrowser::LineArea *m_lineArea; JumpLines *m_jl; -}; + class LineArea : public QWidget { public: LineArea(FlowLineTextBrowser *browser) : QWidget(browser) { + setMouseTracking(true); m_browser = browser; } @@ -74,11 +74,41 @@ protected: void wheelEvent(QWheelEvent *ev) Q_DECL_OVERRIDE { m_browser->proxyWheelEvent(ev); } + bool event(QEvent *event) Q_DECL_OVERRIDE + { + if (event->type() == QEvent::ToolTip) { + QHelpEvent *helpEvent = static_cast(event); + int index = getChannelForXPos(helpEvent->pos().x()); + if (index != -1) { + QToolTip::showText(helpEvent->globalPos(), QString("Channel %1").arg(index)); + } else { + QToolTip::hideText(); + event->ignore(); + } + + return true; + } + return QWidget::event(event); + } + + int getChannelForXPos(int xpos) + { + for (int idx = 0; idx < m_browser->m_jl->m_maxChannel; idx++) + { + int channeloffset = m_browser->getChannelOffset(idx); + if (abs(channeloffset - xpos) < 4) + { + return idx; + } + } + return -1; + } + private: FlowLineTextBrowser *m_browser; JumpLines *m_jl; }; - +}; #endif // FLOWLINETEXTBROWSER_H diff --git a/src/ui/widgets/notesdialog.cpp b/src/ui/widgets/notesdialog.cpp new file mode 100644 index 0000000..fc0fbf6 --- /dev/null +++ b/src/ui/widgets/notesdialog.cpp @@ -0,0 +1,27 @@ +#include "notesdialog.h" +#include "ui_notesdialog.h" +#include + +NotesDialog::NotesDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::NotesDialog) +{ + ui->setupUi(this); + QByteArray text; + QFile notes(":/notes/notes.txt"); + if (notes.open(QIODevice::ReadOnly | QIODevice::Text)) + { + text = notes.readAll(); + notes.close(); + } + else + { + text = "No notes available right now! Maybe next version!"; + } + ui->notesArea->setMarkdown(text); +} + +NotesDialog::~NotesDialog() +{ + delete ui; +} diff --git a/src/ui/widgets/notesdialog.h b/src/ui/widgets/notesdialog.h new file mode 100644 index 0000000..2a89df7 --- /dev/null +++ b/src/ui/widgets/notesdialog.h @@ -0,0 +1,22 @@ +#ifndef NOTESDIALOG_H +#define NOTESDIALOG_H + +#include + +namespace Ui { +class NotesDialog; +} + +class NotesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NotesDialog(QWidget *parent = nullptr); + ~NotesDialog(); + +private: + Ui::NotesDialog *ui; +}; + +#endif // NOTESDIALOG_H diff --git a/src/ui/widgets/notesdialog.ui b/src/ui/widgets/notesdialog.ui new file mode 100644 index 0000000..38ff906 --- /dev/null +++ b/src/ui/widgets/notesdialog.ui @@ -0,0 +1,86 @@ + + + NotesDialog + + + + 0 + 0 + 479 + 409 + + + + Dialog + + + + + + + 12 + + + + Application Notes + + + + + + + true + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + + + buttonBox + accepted() + NotesDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + NotesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +