mirror of
https://git.code.sf.net/p/newrpl/sources
synced 2024-11-16 19:51:25 +01:00
1881 lines
52 KiB
C++
1881 lines
52 KiB
C++
/*
|
|
* Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team
|
|
* All rights reserved.
|
|
* This file is released under the 3-clause BSD license.
|
|
* See the file LICENSE.txt that shipped with this distribution.
|
|
*/
|
|
|
|
#include <QtGui>
|
|
#include <QtCore>
|
|
#include <QFileDialog>
|
|
#include <QFile>
|
|
#include <QFileInfo>
|
|
#include <QMessageBox>
|
|
#include <QKeyEvent>
|
|
#include <QStandardPaths>
|
|
|
|
#include "hidapi.h"
|
|
#include "usbselector.h"
|
|
#include "mainwindow.h"
|
|
#include "ui_mainwindow.h"
|
|
|
|
// ONLY REQUIRED UNDER MINGW
|
|
#ifdef DrawText
|
|
#undef DrawText
|
|
#endif
|
|
#define WORD _WORD
|
|
|
|
extern "C"
|
|
{
|
|
#include "ui.h"
|
|
#include "firmware.h"
|
|
}
|
|
#define takemax(a,b) (((a)>(b))? (a):(b))
|
|
|
|
MainWindow *myMainWindow;
|
|
|
|
// CAN'T INCLUDE THE HEADERS DIRECTLY DUE TO CONFLICTING TYPES ON WINDOWS ONLY...
|
|
|
|
extern unsigned long long __pckeymatrix;
|
|
extern int __pc_terminate;
|
|
extern int __memmap_intact;
|
|
extern volatile int __cpu_idle;
|
|
extern hid_device *__usb_curdevice;
|
|
extern char __usb_devicepath[8192];
|
|
extern volatile int __usb_paused;
|
|
|
|
extern "C" void usb_irqservice();
|
|
extern "C" void usb_irqdisconnect();
|
|
extern "C" void usb_irqconnect();
|
|
extern "C" int usb_isconnected();
|
|
|
|
extern "C" void __keyb_update();
|
|
// BACKUP/RESTORE
|
|
extern "C" int rplBackup(int (*writefunc)(unsigned int, void *), void *);
|
|
extern "C" int rplRestoreBackup(int, unsigned int (*readfunc)(void *), void *);
|
|
extern "C" int rplRestoreBackupMessedup(unsigned int (*readfunc)(void *), void *); // DEBUG ONLY
|
|
extern "C" void __SD_irqeventinsert();
|
|
|
|
extern int __sd_inserted;
|
|
extern int __sd_nsectors; // TOTAL SIZE OF SD CARD IN 512-BYTE SECTORS
|
|
extern int __sd_RCA;
|
|
extern unsigned char *__sd_buffer; // BUFFER WITH THE ENTIRE CONTENTS OF THE SD CARD
|
|
|
|
extern "C" int usbremotearchivestart();
|
|
extern "C" int usbreceivearchive(uint32_t * buffer, int bufsize);
|
|
extern "C" int usbremoterestorestart();
|
|
extern "C" int usbsendarchive(uint32_t * buffer, int bufsize);
|
|
extern "C" int change_autorcv(int newfl);
|
|
|
|
extern "C" void setExceptionPoweroff();
|
|
|
|
MainWindow::MainWindow(QWidget * parent):
|
|
QMainWindow(parent), rpl(this), usbdriver(this), ui(new Ui::MainWindow)
|
|
{
|
|
|
|
QCoreApplication::setOrganizationName("newRPL");
|
|
QCoreApplication::setApplicationName("newRPL Desktop");
|
|
|
|
myMainWindow = this;
|
|
|
|
ui->setupUi(this);
|
|
|
|
ui->KeybImage->setAttribute(Qt::WA_AcceptTouchEvents);
|
|
ui->KeybImage->installEventFilter(this);
|
|
ui->EmuScreen->setAttribute(Qt::WA_AcceptTouchEvents);
|
|
ui->EmuScreen->installEventFilter(this);
|
|
|
|
nousbupdate = true; // DON'T UPDATE THE ON-SCREEN USB CONNECTION STATUS
|
|
__usb_devicepath[0] = 0; // NULL PATH
|
|
__usb_curdevice = 0; // USB IS INITIALLY DISCONNECTED
|
|
__usb_paused = 1; // PAUSE THE USB THREAD
|
|
currentusb.clear();
|
|
currentusbpath.clear();
|
|
|
|
usbdriver.start(); // LAUNCH THE USB DRIVER THREAD
|
|
|
|
ui->USBDockSelect->setVisible(false);
|
|
screentmr = new QTimer(this);
|
|
ui->EmuScreen->setTimer(screentmr);
|
|
ui->EmuScreen->connect(screentmr, SIGNAL(timeout()), ui->EmuScreen,
|
|
SLOT(update()));
|
|
connect(screentmr, SIGNAL(timeout()), this, SLOT(usbupdate()));
|
|
__memmap_intact = 0;
|
|
__sd_inserted = 0;
|
|
__sd_RCA = 0;
|
|
__sd_nsectors = 0;
|
|
__sd_buffer = NULL;
|
|
ui->actionEject_SD_Card_Image->setEnabled(false);
|
|
ui->actionInsert_SD_Card_Image->setEnabled(true);
|
|
|
|
//rpl.start();
|
|
//maintmr->start(1);
|
|
//screentmr->start(20);
|
|
setWindowTitle("newRPL - [Unnamed]");
|
|
|
|
QSettings settings;
|
|
|
|
QString startfile = settings.value("CurrentFile", QString("")).toString();
|
|
|
|
if(!OpenFile(startfile)) {
|
|
rpl.start();
|
|
screentmr->setSingleShot(true);
|
|
screentmr->start(20);
|
|
}
|
|
|
|
}
|
|
|
|
MainWindow::~MainWindow()
|
|
{
|
|
delete screentmr;
|
|
delete ui;
|
|
}
|
|
|
|
void MainWindow::closeEvent(QCloseEvent * event)
|
|
{
|
|
on_actionExit_triggered();
|
|
|
|
event->accept();
|
|
|
|
}
|
|
|
|
void MainWindow::resizeEvent(QResizeEvent * event)
|
|
{
|
|
int w, h;
|
|
qreal scale;
|
|
|
|
//qreal realdpi=qApp->primaryScreen()->logicalDotsPerInch();
|
|
qreal dpratio = qApp->primaryScreen()->devicePixelRatio();
|
|
w = ui->EmuScreen->screen_width;
|
|
h = ui->EmuScreen->screen_height + 5;
|
|
if(!h)
|
|
h = SCREEN_HEIGHT+5;
|
|
if(!w)
|
|
w = SCREEN_WIDTH;
|
|
qreal dpwidth = event->size().width();
|
|
qreal realwidth = dpwidth * dpratio;
|
|
scale = realwidth / w;
|
|
if((int)scale < 1)
|
|
scale = 1.0;
|
|
else
|
|
scale = (int)scale;
|
|
if(event->size().height() * 0.38 * dpratio < scale * h) {
|
|
scale = event->size().height() * 0.38 * dpratio / h;
|
|
if((int)scale < 1)
|
|
scale = 1.0;
|
|
else
|
|
scale = (int)scale;
|
|
}
|
|
// NOW CONVERT BACK TO dp SCALE
|
|
ui->EmuScreen->setScale(scale / dpratio);
|
|
|
|
}
|
|
|
|
void MainWindow::on_EmuScreen_destroyed()
|
|
{
|
|
if(rpl.isRunning())
|
|
rpl.terminate();
|
|
QMainWindow::close();
|
|
}
|
|
|
|
extern volatile long long __pcsystmr;
|
|
int __tmr_singleshot_running = 0;
|
|
volatile unsigned long long __tmr1_msec;
|
|
|
|
extern "C" void __tmr_newirqeventsvc();
|
|
|
|
extern "C" void stop_singleshot()
|
|
{
|
|
__tmr_singleshot_running = 0;
|
|
}
|
|
|
|
extern "C" void timer_singleshot(int msec)
|
|
{
|
|
__tmr1_msec = msec;
|
|
__tmr_singleshot_running = 1;
|
|
}
|
|
|
|
|
|
#ifndef TARGET_PC_PRIMEG1
|
|
|
|
const int keyMap[] = {
|
|
/*
|
|
|
|
KEYBOARD BIT MAP
|
|
----------------
|
|
This is the bit number in the 64-bit keymatrix.
|
|
Bit set means key is pressed.
|
|
|
|
A]-+ B]-+ C]-+ D]-+ E]-+ F]-+
|
|
|41| |42| |43| |44| |45| |46|
|
|
+--+ +--+ +--+ +--+ +--+ +--+
|
|
|
|
G]-+ H]-+ I]-+ UP]+
|
|
|47| |53| |54| |49|
|
|
+--+ +--+ +--+ LF]+ +--+ RT]+
|
|
|50| DN]+ |52|
|
|
J]-+ K]-+ L]-+ +--+ |51| +--+
|
|
|55| |57| |58| +--+
|
|
+--+ +--+ +--+
|
|
|
|
M]--+ N]--+ O]--+ P]--+ BKS]+
|
|
| 33| | 25| | 17| | 09| | 01|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
Q]--+ R]--+ S]--+ T]--+ U]--+
|
|
| 34| | 26| | 18| | 10| | 02|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
V]--+ W]--+ X]--+ Y]--+ /]--+
|
|
| 35| | 27| | 19| | 11| | 03|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
AL]-+ 7]--+ 8]--+ 9]--+ *]--+
|
|
| 60| | 28| | 20| | 12| | 04|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
LS]-+ 4]--+ 5]--+ 6]--+ -]--+
|
|
| 61| | 29| | 21| | 13| | 05|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
RS]-+ 1]--+ 2]--+ 3]--+ +]--+
|
|
| 62| | 30| | 22| | 14| | 06|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
ON]-+ 0]--+ .]--+ SP]-+ EN]-+
|
|
| 63| | 31| | 23| | 15| | 07|
|
|
+---+ +---+ +---+ +---+ +---+
|
|
|
|
*/
|
|
Qt::Key_Backspace, 1,
|
|
Qt::Key_U, 2,
|
|
Qt::Key_Slash, 3,
|
|
Qt::Key_Z, 3,
|
|
Qt::Key_Asterisk, 4,
|
|
Qt::Key_Minus, 5,
|
|
Qt::Key_Plus, 6,
|
|
Qt::Key_Return, 7,
|
|
Qt::Key_Enter, 7,
|
|
Qt::Key_P, 9,
|
|
Qt::Key_T, 10,
|
|
Qt::Key_Y, 11,
|
|
Qt::Key_9, 12,
|
|
Qt::Key_6, 13,
|
|
Qt::Key_3, 14,
|
|
Qt::Key_Space, 15,
|
|
Qt::Key_O, 17,
|
|
Qt::Key_S, 18,
|
|
Qt::Key_X, 19,
|
|
Qt::Key_8, 20,
|
|
Qt::Key_5, 21,
|
|
Qt::Key_2, 22,
|
|
Qt::Key_Period, 23,
|
|
Qt::Key_N, 25,
|
|
Qt::Key_R, 26,
|
|
Qt::Key_W, 27,
|
|
Qt::Key_7, 28,
|
|
Qt::Key_4, 29,
|
|
Qt::Key_1, 30,
|
|
Qt::Key_0, 31,
|
|
Qt::Key_M, 33,
|
|
Qt::Key_Q, 34,
|
|
Qt::Key_V, 35,
|
|
Qt::Key_A, 41,
|
|
Qt::Key_F1, 41,
|
|
Qt::Key_B, 42,
|
|
Qt::Key_F2, 42,
|
|
Qt::Key_C, 43,
|
|
Qt::Key_F3, 43,
|
|
Qt::Key_D, 44,
|
|
Qt::Key_F4, 44,
|
|
Qt::Key_E, 45,
|
|
Qt::Key_F5, 45,
|
|
Qt::Key_F, 46,
|
|
Qt::Key_F6, 46,
|
|
Qt::Key_G, 47,
|
|
Qt::Key_Up, 49,
|
|
Qt::Key_Left, 50,
|
|
Qt::Key_Down, 51,
|
|
Qt::Key_Right, 52,
|
|
Qt::Key_H, 53,
|
|
Qt::Key_I, 54,
|
|
Qt::Key_J, 55,
|
|
Qt::Key_K, 57,
|
|
Qt::Key_L, 58,
|
|
Qt::Key_Tab, 60,
|
|
Qt::Key_CapsLock, 61,
|
|
Qt::Key_Control, 62,
|
|
Qt::Key_Escape, 63,
|
|
Qt::Key_Home, 63
|
|
// ADD MORE KEYS HERE
|
|
, 0, 0
|
|
};
|
|
|
|
struct mousemap
|
|
{
|
|
int key, keynum;
|
|
qreal left, right, top, bot;
|
|
} mouseMap[] = {
|
|
{Qt::Key_Backspace, 1, 0.842672, 0.982759, 0.335196, 0.383613},
|
|
{Qt::Key_U, 2, 0.842672, 0.982759, 0.428305, 0.482309},
|
|
{Qt::Key_Z, 3, 0.842672, 0.982759, 0.527002, 0.575419},
|
|
{Qt::Key_Asterisk, 4, 0.842672, 0.982759, 0.616387, 0.683426},
|
|
{Qt::Key_Minus, 5, 0.842672, 0.982759, 0.716946, 0.783985},
|
|
{Qt::Key_Plus, 6, 0.842672, 0.982759, 0.817505, 0.886406},
|
|
{Qt::Key_Enter, 7, 0.842672, 0.982759, 0.918063, 0.979516},
|
|
|
|
{Qt::Key_P, 9, 0.637931, 0.778017, 0.335196, 0.383613},
|
|
{Qt::Key_T, 10, 0.637931, 0.778017, 0.428305, 0.482309},
|
|
{Qt::Key_Y, 11, 0.637931, 0.778017, 0.527002, 0.575419},
|
|
{Qt::Key_9, 12, 0.637931, 0.778017, 0.616387, 0.683426},
|
|
{Qt::Key_6, 13, 0.637931, 0.778017, 0.716946, 0.783985},
|
|
{Qt::Key_3, 14, 0.637931, 0.778017, 0.817505, 0.886406},
|
|
{Qt::Key_Space, 15, 0.637931, 0.778017, 0.918063, 0.979516},
|
|
|
|
{Qt::Key_O, 17, 0.428879, 0.573276, 0.335196, 0.383613},
|
|
{Qt::Key_S, 18, 0.428879, 0.573276, 0.428305, 0.482309},
|
|
{Qt::Key_X, 19, 0.428879, 0.573276, 0.527002, 0.575419},
|
|
{Qt::Key_8, 20, 0.428879, 0.573276, 0.616387, 0.683426},
|
|
{Qt::Key_5, 21, 0.428879, 0.573276, 0.716946, 0.783985},
|
|
{Qt::Key_2, 22, 0.428879, 0.573276, 0.817505, 0.886406},
|
|
{Qt::Key_Period, 23, 0.428879, 0.573276, 0.918063, 0.979516},
|
|
|
|
{Qt::Key_N, 25, 0.217672, 0.364224, 0.335196, 0.383613},
|
|
{Qt::Key_R, 26, 0.217672, 0.364224, 0.428305, 0.482309},
|
|
{Qt::Key_W, 27, 0.217672, 0.364224, 0.527002, 0.575419},
|
|
{Qt::Key_7, 28, 0.217672, 0.364224, 0.616387, 0.683426},
|
|
{Qt::Key_4, 29, 0.217672, 0.364224, 0.716946, 0.783985},
|
|
{Qt::Key_1, 30, 0.217672, 0.364224, 0.817505, 0.886406},
|
|
{Qt::Key_0, 31, 0.217672, 0.364224, 0.918063, 0.979516},
|
|
|
|
{Qt::Key_M, 33, 0.00862069, 0.153017, 0.335196, 0.383613},
|
|
{Qt::Key_Q, 34, 0.00862069, 0.153017, 0.428305, 0.482309},
|
|
{Qt::Key_V, 35, 0.00862069, 0.153017, 0.527002, 0.575419},
|
|
|
|
{Qt::Key_F1, 41, 0.00862069, 0.118534, 0.00931099, 0.0521415},
|
|
{Qt::Key_F2, 42, 0.181034, 0.295259, 0.00931099, 0.0521415},
|
|
{Qt::Key_F3, 43, 0.357759, 0.467672, 0.00931099, 0.0521415},
|
|
{Qt::Key_F4, 44, 0.530172, 0.642241, 0.00931099, 0.0521415},
|
|
{Qt::Key_F5, 45, 0.706897, 0.814655, 0.00931099, 0.0521415},
|
|
{Qt::Key_F6, 46, 0.872845, 0.987069, 0.00931099, 0.0521415},
|
|
{Qt::Key_G, 47, 0.00862069, 0.118534, 0.108007, 0.163873},
|
|
{Qt::Key_Up, 49, 0.706897, 0.803879, 0.0893855, 0.156425},
|
|
{Qt::Key_Left, 50, 0.581897, 0.678879, 0.150838, 0.230912},
|
|
{Qt::Key_Down, 51, 0.706897, 0.803879, 0.219739, 0.292365},
|
|
{Qt::Key_Right, 52, 0.838362, 0.937500, 0.150838, 0.230912},
|
|
{Qt::Key_H, 53, 0.181034, 0.295259, 0.108007, 0.163873},
|
|
{Qt::Key_I, 54, 0.357759, 0.467672, 0.108007, 0.163873},
|
|
{Qt::Key_J, 55, 0.00862069, 0.118534, 0.221601, 0.271881},
|
|
{Qt::Key_K, 57, 0.181034, 0.295259, 0.221601, 0.271881},
|
|
{Qt::Key_L, 58, 0.357759, 0.467672, 0.221601, 0.271881},
|
|
|
|
{Qt::Key_Tab, 60, 0.00862069, 0.161638, 0.616387, 0.683426},
|
|
{Qt::Key_CapsLock, 61, 0.00862069, 0.161638, 0.716946, 0.783985},
|
|
{Qt::Key_Control, 62, 0.00862069, 0.161638, 0.817505, 0.886406},
|
|
{Qt::Key_Home, 63, 0.00862069, 0.118534, 0.918063, 0.979516},
|
|
|
|
{Qt::Key_F10, 64, 0.872845, 0.987069, 0.108007, 0.163873},
|
|
|
|
// ADD MORE KEYS HERE
|
|
|
|
{0, 0, 0.0, 0.0, 0.0, 0.0}
|
|
|
|
};
|
|
|
|
#else
|
|
|
|
|
|
|
|
const int keyMap[] = {
|
|
/*
|
|
|
|
KEYBOARD BIT MAP
|
|
----------------
|
|
This is the bit number in the 64-bit keymatrix.
|
|
Bit set means key is pressed.
|
|
|
|
AP]+ SY]+ HL]+ ES]+
|
|
|36| |20| |61| |52|
|
|
+--+ +--+ +--+ +--+
|
|
|
|
HM]+ PL]+ UP]+ VW]+ CA]+
|
|
|28| |12| |37| |29| |13|
|
|
+--+ +--+ LF]+ +--+ RT]+ +--+ +--+
|
|
|57| DN]+ |15|
|
|
NM]+ +--+ |44| +--+ ME]+
|
|
|04| +--+ |21|
|
|
+--+ +--+
|
|
|
|
A]--+ B]--+ C]--+ D]--+ E]--+ BKS]+
|
|
| 42| | 58| | 18| | 10| | 34| | 02|
|
|
+---+ +---+ +---+ +---+ +---+ +---+
|
|
|
|
F]--+ G]--+ H]--+ I]--+ J]--+ K]--+
|
|
| 59| | 50| | 43| | 35| | 27| | 19|
|
|
+---+ +---+ +---+ +---+ +---+ +---+
|
|
|
|
L]--+ M]--+ N]--+ O]--+ ENTER]-----+
|
|
| 11| | 03| | 60| | 06| | 07 |
|
|
+---+ +---+ +---+ +---+ +----------+
|
|
|
|
P]--+ 7]---+ 8]---+ 9]---+ /]--+
|
|
| 01| | 22 | | 14 | | 05 | | 17|
|
|
+---+ +----+ +----+ +----+ +---+
|
|
|
|
AL]-+ 4]---+ 5]---+ 6]---+ *]--+
|
|
| 26| | 46 | | 38 | | 30 | | 25|
|
|
+---+ +----+ +----+ +----+ +---+
|
|
|
|
RS]-+ 1]---+ 2]---+ 3]---+ -]--+
|
|
| 51| | 45 | | 62 | | 54 | | 33|
|
|
+---+ +----+ +----+ +----+ +---+
|
|
|
|
ON]-+ 0]---+ .]---+ SP]--+ +]--+
|
|
| 63| | 09 | | 53 | | 49 | | 41|
|
|
+---+ +----+ +----+ +----+ +---+
|
|
|
|
*/
|
|
|
|
Qt::Key_Backspace, 2,
|
|
Qt::Key_U, 36,
|
|
Qt::Key_Slash, 17,
|
|
Qt::Key_Z, 17,
|
|
Qt::Key_Asterisk, 25,
|
|
Qt::Key_Minus, 33,
|
|
Qt::Key_Plus, 41,
|
|
Qt::Key_Return, 7,
|
|
Qt::Key_Enter, 7,
|
|
Qt::Key_P, 1,
|
|
Qt::Key_T, 13,
|
|
Qt::Key_Y, 61,
|
|
Qt::Key_9, 5,
|
|
Qt::Key_6, 30,
|
|
Qt::Key_3, 54,
|
|
Qt::Key_Space, 49,
|
|
Qt::Key_O, 6,
|
|
Qt::Key_S, 21,
|
|
Qt::Key_X, 20,
|
|
Qt::Key_8, 14,
|
|
Qt::Key_5, 38,
|
|
Qt::Key_2, 62,
|
|
Qt::Key_Period, 53,
|
|
Qt::Key_N, 60,
|
|
Qt::Key_R, 4,
|
|
Qt::Key_W, 29,
|
|
Qt::Key_7, 22,
|
|
Qt::Key_4, 46,
|
|
Qt::Key_1, 45,
|
|
Qt::Key_0, 9,
|
|
Qt::Key_M, 3,
|
|
Qt::Key_Q, 28,
|
|
Qt::Key_V, 12,
|
|
Qt::Key_A, 42,
|
|
Qt::Key_F1, 20,
|
|
Qt::Key_B, 58,
|
|
Qt::Key_F2, 12,
|
|
Qt::Key_C, 18,
|
|
Qt::Key_F3, 4,
|
|
Qt::Key_D, 10,
|
|
Qt::Key_F4, 61,
|
|
Qt::Key_E, 34,
|
|
Qt::Key_F5, 29,
|
|
Qt::Key_F, 59,
|
|
Qt::Key_F6, 21,
|
|
Qt::Key_G, 50,
|
|
Qt::Key_Up, 37,
|
|
Qt::Key_Left, 57,
|
|
Qt::Key_Down, 44,
|
|
Qt::Key_Right, 15,
|
|
Qt::Key_H, 43,
|
|
Qt::Key_I, 35,
|
|
Qt::Key_J, 27,
|
|
Qt::Key_K, 19,
|
|
Qt::Key_L, 11,
|
|
Qt::Key_Tab, 26,
|
|
Qt::Key_CapsLock, 51,
|
|
Qt::Key_Control, 63,
|
|
Qt::Key_Escape, 52,
|
|
Qt::Key_Home, 28
|
|
// ADD MORE KEYS HERE
|
|
, 0, 0
|
|
};
|
|
|
|
struct mousemap
|
|
{
|
|
int key, keynum;
|
|
qreal left, right, top, bot;
|
|
} mouseMap[] = {
|
|
{Qt::Key_Escape, 52, 0.836036, 0.960360, 0.030631, 0.104286},
|
|
{Qt::Key_T, 13, 0.836036, 0.960360, 0.137143, 0.214286},
|
|
|
|
{Qt::Key_Backspace, 2, 0.836036, 0.960360, 0.270000, 0.345714},
|
|
{Qt::Key_K, 19, 0.836036, 0.960360, 0.372857, 0.448571},
|
|
{Qt::Key_Enter, 7, 0.675676, 0.960360, 0.477143, 0.557143},
|
|
|
|
{Qt::Key_Slash, 17, 0.836036, 0.960360, 0.580000, 0.660000},
|
|
{Qt::Key_Asterisk, 25, 0.836036, 0.960360, 0.687143, 0.762857},
|
|
{Qt::Key_Minus, 33, 0.836036, 0.960360, 0.791429, 0.867143},
|
|
{Qt::Key_Plus, 41, 0.836036, 0.960360, 0.894286, 0.972857},
|
|
|
|
{Qt::Key_Y, 61, 0.677477, 0.798198, 0.015714, 0.067143},
|
|
{Qt::Key_W, 29, 0.677477, 0.798198, 0.094286, 0.145714},
|
|
{Qt::Key_S, 21, 0.677477, 0.798198, 0.172857, 0.222857},
|
|
|
|
{Qt::Key_E, 34, 0.677477, 0.798198, 0.270000, 0.345714},
|
|
{Qt::Key_J, 27, 0.677477, 0.798198, 0.372857, 0.448571},
|
|
|
|
{Qt::Key_9, 5, 0.625225, 0.803604, 0.580000, 0.660000},
|
|
{Qt::Key_6, 30, 0.625225, 0.803604, 0.687143, 0.762857},
|
|
{Qt::Key_3, 54, 0.625225, 0.803604, 0.791429, 0.867143},
|
|
{Qt::Key_Space, 49, 0.625225, 0.803604, 0.894286, 0.972857},
|
|
|
|
{Qt::Key_D, 10, 0.517117, 0.636036, 0.270000, 0.345714},
|
|
{Qt::Key_I, 35, 0.517117, 0.636036, 0.372857, 0.448571},
|
|
{Qt::Key_O, 6, 0.517117, 0.636036, 0.477143, 0.557143},
|
|
|
|
{Qt::Key_C, 18, 0.356757, 0.477477, 0.270000, 0.345714},
|
|
{Qt::Key_H, 43, 0.356757, 0.477477, 0.372857, 0.448571},
|
|
{Qt::Key_N, 60, 0.356757, 0.477477, 0.477143, 0.557143},
|
|
|
|
{Qt::Key_8, 14, 0.410811, 0.585586, 0.580000, 0.660000},
|
|
{Qt::Key_5, 38, 0.410811, 0.585586, 0.687143, 0.762857},
|
|
{Qt::Key_2, 62, 0.410811, 0.585586, 0.791429, 0.867143},
|
|
{Qt::Key_Period, 53, 0.410811, 0.585586, 0.894286, 0.972857},
|
|
|
|
{Qt::Key_X, 20, 0.192793, 0.318919, 0.015714, 0.067143},
|
|
{Qt::Key_V, 12, 0.192793, 0.318919, 0.094286, 0.145714},
|
|
{Qt::Key_R, 04, 0.192793, 0.318919, 0.172857, 0.222857},
|
|
|
|
{Qt::Key_B, 58, 0.192793, 0.318919, 0.270000, 0.345714},
|
|
{Qt::Key_G, 50, 0.192793, 0.318919, 0.372857, 0.448571},
|
|
{Qt::Key_M, 3, 0.192793, 0.318919, 0.477143, 0.557143},
|
|
|
|
{Qt::Key_7, 22, 0.192793, 0.374775, 0.580000, 0.660000},
|
|
{Qt::Key_4, 46, 0.192793, 0.374775, 0.687143, 0.762857},
|
|
{Qt::Key_1, 45, 0.192793, 0.374775, 0.791429, 0.867143},
|
|
{Qt::Key_0, 9, 0.192793, 0.374775, 0.894286, 0.972857},
|
|
|
|
{Qt::Key_U, 36, 0.034234, 0.158559, 0.030631, 0.104286},
|
|
{Qt::Key_Q, 28, 0.034234, 0.158559, 0.137143, 0.214286},
|
|
|
|
{Qt::Key_A, 42, 0.034234, 0.158559, 0.270000, 0.345714},
|
|
{Qt::Key_F, 59, 0.034234, 0.158559, 0.372857, 0.448571},
|
|
{Qt::Key_L, 11, 0.034234, 0.158559, 0.477143, 0.557143},
|
|
{Qt::Key_P, 1, 0.034234, 0.158559, 0.580000, 0.660000},
|
|
|
|
{Qt::Key_Tab, 26, 0.034234, 0.158559, 0.687143, 0.762857},
|
|
{Qt::Key_CapsLock, 51, 0.034234, 0.158559, 0.791429, 0.867143},
|
|
{Qt::Key_Control , 63, 0.034234, 0.158559, 0.894286, 0.972857},
|
|
|
|
{Qt::Key_Up, 37, 0.410811, 0.585586, 0.030631, 0.104286},
|
|
{Qt::Key_Down, 44, 0.410811, 0.585586, 0.149202, 0.222857},
|
|
{Qt::Key_Left, 57, 0.356757, 0.477477, 0.104286, 0.149202},
|
|
{Qt::Key_Right, 15, 0.517117, 0.636036, 0.104286, 0.149202},
|
|
|
|
|
|
// DONE UP TO HERE
|
|
|
|
|
|
// {Qt::Key_F10, 64, 0.872845, 0.987069, 0.108007, 0.163873},
|
|
|
|
// ADD MORE KEYS HERE
|
|
|
|
{0, 0, 0.0, 0.0, 0.0, 0.0}
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void MainWindow::keyPressEvent(QKeyEvent * ev)
|
|
{
|
|
|
|
int i;
|
|
|
|
if(ev->isAutoRepeat()) {
|
|
ev->accept();
|
|
return;
|
|
}
|
|
|
|
if(ev->key() == Qt::Key_F12) {
|
|
__pckeymatrix = (1ULL << 63) | (1ULL << 41) | (1ULL << 43);
|
|
__keyb_update();
|
|
ev->accept();
|
|
return;
|
|
}
|
|
|
|
for(i = 0; keyMap[i] != 0; i += 2) {
|
|
if(ev->key() == keyMap[i]) {
|
|
__pckeymatrix |= 1ULL << (keyMap[i + 1]);
|
|
__keyb_update();
|
|
ev->accept();
|
|
return;
|
|
}
|
|
}
|
|
|
|
QMainWindow::keyPressEvent(ev);
|
|
}
|
|
|
|
void MainWindow::keyReleaseEvent(QKeyEvent * ev)
|
|
{
|
|
|
|
int i;
|
|
if(ev->isAutoRepeat()) {
|
|
ev->accept();
|
|
return;
|
|
}
|
|
|
|
if(ev->key() == Qt::Key_F12) {
|
|
__pckeymatrix &= ~((1ULL << 63) | (1ULL << 41) | (1ULL << 43));
|
|
__keyb_update();
|
|
ev->accept();
|
|
return;
|
|
}
|
|
|
|
int mykey = ev->key();
|
|
|
|
for(i = 0; keyMap[i] != 0; i += 2) {
|
|
if(mykey == keyMap[i]) {
|
|
__pckeymatrix &= ~(1ULL << (keyMap[i + 1]));
|
|
__keyb_update();
|
|
ev->accept();
|
|
return;
|
|
}
|
|
}
|
|
|
|
QMainWindow::keyReleaseEvent(ev);
|
|
}
|
|
|
|
extern "C" void thread_processevents()
|
|
{
|
|
QCoreApplication::processEvents();
|
|
QThread::yieldCurrentThread();
|
|
}
|
|
|
|
void MainWindow::on_actionExit_triggered()
|
|
{
|
|
|
|
// CLEANUP SD CARD EMULATION
|
|
if(__sd_inserted) {
|
|
// STOP RPL ENGINE
|
|
screentmr->stop();
|
|
if(rpl.isRunning()) {
|
|
__cpu_idle = 0;
|
|
__pc_terminate = 1;
|
|
__pckeymatrix ^= (1ULL << 63);
|
|
__keyb_update();
|
|
while(rpl.isRunning()) {
|
|
__pc_terminate = 1;
|
|
}
|
|
|
|
}
|
|
on_actionEject_SD_Card_Image_triggered();
|
|
}
|
|
|
|
// SAVE CURRENT FILE
|
|
if(currentfile.isEmpty()) {
|
|
QMessageBox a(QMessageBox::Warning, "Work not saved",
|
|
"Do you want to save before exit?",
|
|
QMessageBox::Yes | QMessageBox::No, this);
|
|
if(a.exec() == QMessageBox::Yes)
|
|
on_actionSave_triggered();
|
|
}
|
|
else
|
|
on_actionSave_triggered();
|
|
|
|
// STOP RPL ENGINE
|
|
screentmr->stop();
|
|
if(rpl.isRunning()) {
|
|
__cpu_idle = 0;
|
|
__pc_terminate = 1;
|
|
__pckeymatrix ^= (1ULL << 63);
|
|
__keyb_update();
|
|
while(rpl.isRunning()) {
|
|
__pc_terminate = 1;
|
|
}
|
|
}
|
|
|
|
// STOP THE USB DRIVER THREAD
|
|
__usb_paused = 2;
|
|
while(usbdriver.isRunning() && (__usb_paused >= 0));
|
|
|
|
QSettings settings;
|
|
|
|
settings.setValue(QString("CurrentFile"), QVariant(currentfile));
|
|
|
|
}
|
|
|
|
int MainWindow::WriteWord(unsigned int word)
|
|
{
|
|
if(myMainWindow->fileptr->write((const char *)&word, 4) != 4)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
unsigned int MainWindow::ReadWord()
|
|
{
|
|
unsigned int w;
|
|
myMainWindow->fileptr->read((char *)&w, 4);
|
|
return w;
|
|
}
|
|
|
|
extern "C" int write_data(unsigned int word, void *opaque)
|
|
{
|
|
(void)opaque;
|
|
return MainWindow::WriteWord(word);
|
|
}
|
|
|
|
extern "C" unsigned int read_data(void *opaque)
|
|
{
|
|
(void)opaque;
|
|
return MainWindow::ReadWord();
|
|
}
|
|
|
|
void MainWindow::on_actionSave_triggered()
|
|
{
|
|
QString fname;
|
|
QString path = getDocumentsLocation();
|
|
|
|
if(currentfile.isEmpty()) {
|
|
fname = QFileDialog::getSaveFileName(this,
|
|
"Select file name to Save as", path,
|
|
"newRPL Backups (*.nrpb *.* *)");
|
|
if(!fname.isEmpty()) {
|
|
currentfile = fname;
|
|
setWindowTitle(QString("newRPL - [") + fname + QString("]"));
|
|
}
|
|
else
|
|
return;
|
|
|
|
}
|
|
else
|
|
fname = currentfile;
|
|
|
|
SaveFile(fname);
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionOpen_triggered()
|
|
{
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname = QFileDialog::getOpenFileName(this, "Open File Name", path,
|
|
"newRPL Backups (*.nrpb *.* *)",nullptr,QFileDialog::DontUseNativeDialog);
|
|
|
|
if(!OpenFile(fname)) {
|
|
if(!rpl.isRunning()) {
|
|
// RESTART RPL ENGINE
|
|
__pc_terminate = 0;
|
|
__pckeymatrix = 0;
|
|
|
|
rpl.start();
|
|
screentmr->setSingleShot(true);
|
|
screentmr->start(20);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_actionSaveAs_triggered()
|
|
{
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname =
|
|
QFileDialog::getSaveFileName(this, "Select file name to Save as",
|
|
path, "newRPL Backups (*.nrpb *.* *)");
|
|
|
|
if(!fname.isEmpty()) {
|
|
currentfile = fname;
|
|
setWindowTitle(QString("newRPL - [") + fname + QString("]"));
|
|
}
|
|
else
|
|
return;
|
|
|
|
SaveFile(fname);
|
|
}
|
|
|
|
void MainWindow::on_actionNew_triggered()
|
|
{
|
|
|
|
// STOP RPL ENGINE
|
|
screentmr->stop();
|
|
if(rpl.isRunning()) {
|
|
__cpu_idle = 0;
|
|
__pc_terminate = 1;
|
|
__pckeymatrix ^= (1ULL << 63);
|
|
__keyb_update();
|
|
while(rpl.isRunning()) {
|
|
usbupdate();
|
|
__pc_terminate = 1;
|
|
}
|
|
}
|
|
|
|
currentfile.clear();
|
|
setWindowTitle("newRPL - [Unnamed]");
|
|
__memmap_intact = 0;
|
|
|
|
// RESTART RPL ENGINE
|
|
__pc_terminate = 0;
|
|
__pckeymatrix = 0;
|
|
|
|
rpl.start();
|
|
|
|
screentmr->setSingleShot(true);
|
|
screentmr->start(20);
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionInsert_SD_Card_Image_triggered()
|
|
{
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname =
|
|
QFileDialog::getOpenFileName(this, "Open SD Card Image", path,
|
|
"*.img");
|
|
if(!fname.isEmpty()) {
|
|
sdcard.setFileName(fname);
|
|
|
|
if(!sdcard.open(QIODevice::ReadOnly)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"Cannot open file " + fname, QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
__sd_inserted = 0;
|
|
__sd_RCA = 0;
|
|
__sd_nsectors = 0;
|
|
if(__sd_buffer != NULL)
|
|
free(__sd_buffer);
|
|
|
|
// FILE IS OPEN AND READY FOR READING
|
|
__sd_buffer = (unsigned char *)malloc(sdcard.size());
|
|
if(__sd_buffer == NULL) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"Not enough memory to read SD Image", QMessageBox::Ok,
|
|
this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
if(sdcard.read((char *)__sd_buffer, sdcard.size()) != sdcard.size()) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"Can't read SD Image", QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
__sd_nsectors = sdcard.size() / 512;
|
|
__sd_inserted = 1;
|
|
sdcard.close();
|
|
// SIMULATE AN IRQ
|
|
__SD_irqeventinsert();
|
|
|
|
ui->actionEject_SD_Card_Image->setEnabled(true);
|
|
ui->actionInsert_SD_Card_Image->setEnabled(false);
|
|
return;
|
|
}
|
|
|
|
// NOTHING TO MOUNT, KEEP THE PREVIOUS STATUS
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionEject_SD_Card_Image_triggered()
|
|
{
|
|
if(__sd_inserted) {
|
|
// SAVE THE CONTENTS BACK BEFORE EJECTING
|
|
if(!sdcard.open(QIODevice::WriteOnly)) {
|
|
QMessageBox a(QMessageBox::Warning,
|
|
"Error while saving SD Card contents",
|
|
"Cannot open file " + sdcard.fileName(), QMessageBox::Ok,
|
|
this);
|
|
a.exec();
|
|
}
|
|
else {
|
|
sdcard.write((char *)__sd_buffer, (qint64) __sd_nsectors * 512LL);
|
|
sdcard.close();
|
|
}
|
|
}
|
|
__sd_inserted = 0;
|
|
__sd_RCA = 0;
|
|
__sd_nsectors = 0;
|
|
if(__sd_buffer != NULL) {
|
|
free(__sd_buffer);
|
|
__sd_buffer = NULL;
|
|
}
|
|
|
|
// SIMULATE AN IRQ
|
|
__SD_irqeventinsert();
|
|
|
|
ui->actionEject_SD_Card_Image->setEnabled(false);
|
|
ui->actionInsert_SD_Card_Image->setEnabled(true);
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionPower_ON_triggered()
|
|
{
|
|
|
|
// STOP RPL ENGINE
|
|
screentmr->stop();
|
|
if(rpl.isRunning()) {
|
|
__cpu_idle = 0;
|
|
__pc_terminate = 1;
|
|
__pckeymatrix ^= (1ULL << 63);
|
|
__keyb_update();
|
|
while(rpl.isRunning()) {
|
|
__pc_terminate = 1;
|
|
}
|
|
}
|
|
|
|
if(__pc_terminate == 2) {
|
|
// IT WAS POWERED OFF
|
|
__memmap_intact = 2;
|
|
}
|
|
else
|
|
__memmap_intact = 1;
|
|
|
|
// RESTART RPL ENGINE
|
|
__pc_terminate = 0;
|
|
__pckeymatrix = 0;
|
|
|
|
rpl.start();
|
|
screentmr->setSingleShot(true);
|
|
screentmr->start(20);
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionSimulate_Alarm_triggered()
|
|
{
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionTake_Screenshot_triggered()
|
|
{
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname =
|
|
QFileDialog::getSaveFileName(this, "Save screenshot as...", path,
|
|
"*.png");
|
|
if(!fname.isEmpty()) {
|
|
|
|
QRectF r = ui->EmuScreen->sceneRect();
|
|
QImage image(r.width() * 4, r.height() * 4, QImage::Format_ARGB32);
|
|
QPainter painter(&image);
|
|
painter.setRenderHint(QPainter::Antialiasing);
|
|
ui->EmuScreen->scene()->render(&painter);
|
|
image.save(fname);
|
|
}
|
|
}
|
|
|
|
extern void Stack2Clipboard(int level, int dropit);
|
|
extern void Clipboard2Stack();
|
|
extern void Clipboard2StackCompile();
|
|
extern int SaveRPLObject(QString & filename, int level);
|
|
int LoadRPLObject(QString & filename);
|
|
|
|
void MainWindow::on_actionCopy_Level_1_triggered()
|
|
{
|
|
if(!rpl.isRunning())
|
|
return; // DO NOTHING
|
|
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // BLOCK REQUEST
|
|
|
|
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
|
Stack2Clipboard(1, 0);
|
|
|
|
__cpu_idle = 0; // LET GO THE SIMULATOR
|
|
}
|
|
|
|
void MainWindow::on_actionPaste_to_Level_1_triggered()
|
|
{
|
|
if(!rpl.isRunning())
|
|
return; // DO NOTHING
|
|
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // BLOCK REQUEST
|
|
|
|
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
|
Clipboard2Stack();
|
|
|
|
__cpu_idle = 0; // LET GO THE SIMULATOR
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionCut_Level_1_triggered()
|
|
{
|
|
if(!rpl.isRunning())
|
|
return; // DO NOTHING
|
|
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // BLOCK REQUEST
|
|
|
|
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
|
Stack2Clipboard(1, 1);
|
|
|
|
__cpu_idle = 0; // LET GO THE SIMULATOR
|
|
halScreenUpdated();
|
|
}
|
|
|
|
void MainWindow::on_actionSave_Level_1_As_triggered()
|
|
{
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname = QFileDialog::getSaveFileName(this,
|
|
"Select file name to store object", path,
|
|
"newRPL objects (*.nrpl *.* *)");
|
|
|
|
if(!fname.isEmpty()) {
|
|
// GOT A NAME, APPEND EXTENSION IF NOT GIVEN
|
|
|
|
//if(!fname.endsWith(".nrpl")) fname+=".nrpl";
|
|
|
|
if(!SaveRPLObject(fname, 1)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while saving",
|
|
"Cannot write to file " + fname, QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_actionOpen_file_to_Level_1_triggered()
|
|
{
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname = QFileDialog::getOpenFileName(this, "Select File Name", path,
|
|
"newRPL objects (*.nrpl *.* *)",nullptr,QFileDialog::DontUseNativeDialog);
|
|
|
|
if(!fname.isEmpty()) {
|
|
if(!rpl.isRunning())
|
|
return; // DO NOTHING
|
|
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // BLOCK REQUEST
|
|
|
|
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
|
if(!LoadRPLObject(fname)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"Cannot read file. Corrupted data?\n" + fname,
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
__cpu_idle = 0; // LET GO THE SIMULATOR
|
|
halScreenUpdated();
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionConnect_to_calc_triggered()
|
|
{
|
|
ui->USBDockSelect->setVisible(true);
|
|
halScreenUpdated();
|
|
}
|
|
|
|
void MainWindow::usbupdate()
|
|
{
|
|
if(nousbupdate)
|
|
return;
|
|
|
|
if(!usb_isconnected()) {
|
|
if(!currentusb.isEmpty()) {
|
|
// ATTEMPT TO RECONNECT WITH THE DEVICE
|
|
if(ui->usbconnectButton->text().endsWith("[ Click to reconnect ]")) {
|
|
halScreenUpdated();
|
|
// ATTEMPT TO RECONNECT
|
|
__usb_paused = 1;
|
|
while(__usb_paused >= 0);
|
|
usb_shutdown();
|
|
if(safe_stringcpy(__usb_devicepath, 8192,
|
|
currentusbpath.toUtf8().constData()))
|
|
__usb_devicepath[0] = 0;
|
|
usb_init(0);
|
|
if(!usb_isconnected()) {
|
|
return;
|
|
}
|
|
else {
|
|
ui->usbconnectButton->setText(currentusb);
|
|
__usb_paused = 0; // AND RESUME THE DRIVER
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
ui->usbconnectButton->setText(currentusb +
|
|
QString(" [ Click to reconnect ]"));
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void MainWindow::on_usbconnectButton_clicked()
|
|
{
|
|
nousbupdate = true;
|
|
|
|
// PAUSE THE USB DRIVER
|
|
__usb_paused = 1;
|
|
while(__usb_paused >= 0);
|
|
|
|
if(ui->usbconnectButton->text().endsWith("[ Click to reconnect ]")) {
|
|
// ATTEMPT TO RECONNECT
|
|
usb_shutdown();
|
|
if(safe_stringcpy(__usb_devicepath, 8192,
|
|
currentusbpath.toUtf8().constData()))
|
|
__usb_devicepath[0] = 0;
|
|
usb_init(0);
|
|
if(!usb_isconnected()) {
|
|
currentusb.clear();
|
|
currentusbpath.clear();
|
|
}
|
|
else {
|
|
ui->usbconnectButton->setText(currentusb);
|
|
__usb_paused = 0; // AND RESUME THE DRIVER
|
|
halScreenUpdated();
|
|
nousbupdate = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(!usb_isconnected()) {
|
|
currentusb.clear();
|
|
currentusbpath.clear();
|
|
}
|
|
else {
|
|
// DISCONNECT
|
|
ui->usbconnectButton->setText(" [ Select a USB Device ] ");
|
|
usb_shutdown();
|
|
currentusb.clear();
|
|
currentusbpath.clear();
|
|
return;
|
|
}
|
|
|
|
int oldflag;
|
|
if(rpl.isRunning())
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // PAUSE RPL ENGINE UNTIL WE ARE DONE CONNECTING
|
|
|
|
oldflag = change_autorcv(1);
|
|
|
|
__cpu_idle = 0;
|
|
if(rpl.isRunning())
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
USBSelector seldlg;
|
|
|
|
if(seldlg.exec() == QDialog::Accepted) {
|
|
if(!seldlg.getSelectedDevicePath().isEmpty()) {
|
|
usb_shutdown();
|
|
if(safe_stringcpy(__usb_devicepath, 8192,
|
|
seldlg.getSelectedDevicePath().toUtf8().constData()))
|
|
__usb_devicepath[0] = 0;
|
|
usb_init(0);
|
|
if(usb_isconnected()) {
|
|
currentusbpath = seldlg.getSelectedDevicePath();
|
|
currentusbpath.detach();
|
|
currentusb = seldlg.getSelectedDeviceName();
|
|
currentusb.detach();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(currentusb.isEmpty())
|
|
ui->usbconnectButton->setText(" [ Select a USB Device ] ");
|
|
else {
|
|
ui->usbconnectButton->setText(currentusb);
|
|
nousbupdate = false;
|
|
__usb_paused = 0;
|
|
}
|
|
|
|
if(rpl.isRunning()) {
|
|
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // PAUSE RPL ENGINE UNTIL WE ARE DONE CONNECTING
|
|
|
|
}
|
|
change_autorcv(oldflag);
|
|
|
|
__cpu_idle = 0;
|
|
|
|
halScreenUpdated();
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionUSB_Remote_ARCHIVE_to_file_triggered()
|
|
{
|
|
|
|
if(!usb_isconnected()) {
|
|
QMessageBox a(QMessageBox::Warning, "USB not connected",
|
|
"Need to establish a connection to a device first.",
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname =
|
|
QFileDialog::getSaveFileName(this, "Select file name to Save as",
|
|
path, "newRPL Backups (*.nrpb *.* *)");
|
|
|
|
if(!fname.isEmpty()) {
|
|
// GOT A NAME, APPEND EXTENSION IF NOT GIVEN
|
|
|
|
//if(!fname.endsWith(".nrpb")) fname+=".nrpb";
|
|
|
|
QFile file(fname);
|
|
|
|
if(!file.open(QIODevice::WriteOnly)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while saving",
|
|
"Cannot write to file " + fname, QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
// FILE IS OPEN AND READY FOR WRITING
|
|
|
|
if(!usbremotearchivestart()) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while saving",
|
|
"Failed to send remote commands to " + currentusb,
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
file.close();
|
|
return;
|
|
}
|
|
|
|
#define USBARCHIVE_MAX_SIZE_WORDS 1024*1024
|
|
|
|
uint32_t *buffer = new uint32_t[USBARCHIVE_MAX_SIZE_WORDS]; // 4 MB EXPECTED MAXIMUM SIZE OF AN ARCHIVE
|
|
if(!buffer) {
|
|
file.close(); // RETURN - THIS WILL NEVER HAPPEN FOR JUST 4 MB
|
|
return;
|
|
}
|
|
|
|
int oldflag;
|
|
if(rpl.isRunning())
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // PAUSE RPL ENGINE UNTIL WE ARE DONE CONNECTING
|
|
|
|
oldflag = change_autorcv(1); // STOP THE SIMULATOR FROM RECEIVING THR TRANSMISSION
|
|
|
|
__cpu_idle = 0;
|
|
|
|
int nwords = usbreceivearchive(buffer, USBARCHIVE_MAX_SIZE_WORDS);
|
|
|
|
if(rpl.isRunning())
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // PAUSE RPL ENGINE UNTIL WE ARE DONE CONNECTING
|
|
|
|
change_autorcv(oldflag); // RESTORE THE SIMULATOR FLAG
|
|
|
|
__cpu_idle = 0;
|
|
|
|
if(nwords == -1) {
|
|
file.close();
|
|
QMessageBox a(QMessageBox::Warning, "Error while saving",
|
|
"USB communication error", QMessageBox::Ok, this);
|
|
a.exec();
|
|
delete[]buffer;
|
|
return;
|
|
}
|
|
|
|
file.write((const char *)buffer, nwords * sizeof(uint32_t));
|
|
|
|
file.close();
|
|
|
|
delete[]buffer;
|
|
|
|
}
|
|
}
|
|
|
|
void MainWindow::on_actionRemote_USBRESTORE_from_file_triggered()
|
|
{
|
|
if(!usb_isconnected()) {
|
|
QMessageBox a(QMessageBox::Warning, "USB not connected",
|
|
"Need to establish a connection to a device first.",
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
QString path = getDocumentsLocation();
|
|
|
|
QString fname = QFileDialog::getOpenFileName(this, "Open File Name", path,
|
|
"newRPL Backups (*.nrpb *.* *)",nullptr,QFileDialog::DontUseNativeDialog);
|
|
|
|
if(!fname.isEmpty()) {
|
|
QFile file(fname);
|
|
|
|
if(!file.open(QIODevice::ReadOnly)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"Cannot open file " + fname, QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
// FILE IS OPEN AND READY FOR READING
|
|
|
|
QByteArray filedata;
|
|
|
|
filedata = file.readAll();
|
|
|
|
file.close();
|
|
|
|
QMessageBox warn(QMessageBox::Warning, "Remote USBRESTORE",
|
|
"USBRESTORE will completely replace *ALL DATA* on the connected device with no way to undo the operation. OK to proceed?",
|
|
QMessageBox::Yes | QMessageBox::No, this);
|
|
|
|
if(warn.exec() == QMessageBox::Yes) {
|
|
|
|
if(!usbremoterestorestart()) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while restoring",
|
|
"Failed to send remote commands to " + currentusb,
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
int oldflag;
|
|
|
|
if(rpl.isRunning())
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
__cpu_idle = 2; // PAUSE RPL ENGINE UNTIL WE ARE DONE CONNECTING
|
|
|
|
oldflag = change_autorcv(1); // STOP THE SIMULATOR FROM RECEIVING THR TRANSMISSION
|
|
|
|
__cpu_idle = 0;
|
|
|
|
int nwords =
|
|
usbsendarchive((uint32_t *) filedata.constData(),
|
|
(filedata.size() + 3) >> 2);
|
|
|
|
if(rpl.isRunning())
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // PAUSE RPL ENGINE UNTIL WE ARE DONE CONNECTING
|
|
|
|
change_autorcv(oldflag); // RESTORE THE SIMULATOR FLAG
|
|
|
|
__cpu_idle = 0;
|
|
|
|
halScreenUpdated();
|
|
|
|
if(nwords == -1) {
|
|
file.close();
|
|
QMessageBox a(QMessageBox::Warning, "Error while restoring",
|
|
"USB communication error", QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
int MainWindow::OpenFile(QString fname)
|
|
{
|
|
if(!fname.isEmpty()) {
|
|
QFile file(fname);
|
|
|
|
if(!file.open(QIODevice::ReadOnly)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"Cannot open file " + fname, QMessageBox::Ok, this);
|
|
a.exec();
|
|
return 0;
|
|
}
|
|
|
|
// FILE IS OPEN AND READY FOR READING
|
|
|
|
// STOP RPL ENGINE
|
|
screentmr->stop();
|
|
if(rpl.isRunning()) {
|
|
__cpu_idle = 0;
|
|
__pc_terminate = 1;
|
|
__pckeymatrix ^= (1ULL << 63);
|
|
__keyb_update();
|
|
while(rpl.isRunning()) {
|
|
usbupdate();
|
|
__pc_terminate = 1;
|
|
}
|
|
}
|
|
|
|
// PERFORM RESTORE PROCEDURE
|
|
myMainWindow = this;
|
|
fileptr = &file;
|
|
int result = rplRestoreBackup(1, &read_data, (void *)fileptr);
|
|
|
|
file.close();
|
|
|
|
switch (result) {
|
|
case -1:
|
|
{
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"File " + fname +
|
|
" is corrupt or incompatible.\nCan't recover and memory was destroyed.",
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
currentfile.clear();
|
|
setWindowTitle("newRPL - [Unnamed]");
|
|
__memmap_intact = 0;
|
|
return 0;
|
|
}
|
|
case 0:
|
|
{
|
|
QMessageBox a(QMessageBox::Warning, "Error while opening",
|
|
"File " + fname +
|
|
" is corrupt or incompatible.\nCan't recover but memory was left intact.",
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
__memmap_intact = 1;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
currentfile = fname;
|
|
QString nameonly =
|
|
currentfile.right(currentfile.length() - 1 -
|
|
takemax(currentfile.lastIndexOf("/"),
|
|
currentfile.lastIndexOf("\\")));
|
|
setWindowTitle("newRPL - [" + nameonly + "]");
|
|
|
|
__memmap_intact = 2;
|
|
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
QMessageBox a(QMessageBox::Warning, "Recovery success",
|
|
"File " + fname +
|
|
" was recovered with minor errors.\nRun MEMFIX to correct them.",
|
|
QMessageBox::Ok, this);
|
|
a.exec();
|
|
currentfile = fname;
|
|
QString nameonly =
|
|
currentfile.right(currentfile.length() - 1 -
|
|
takemax(currentfile.lastIndexOf("/"),
|
|
currentfile.lastIndexOf("\\")));
|
|
setWindowTitle("newRPL - [" + nameonly + "]");
|
|
|
|
__memmap_intact = 1;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
// RESTART RPL ENGINE
|
|
__pc_terminate = 0;
|
|
__pckeymatrix = 0;
|
|
|
|
rpl.start();
|
|
screentmr->setSingleShot(true);
|
|
screentmr->start(20);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void MainWindow::SaveFile(QString fname)
|
|
{
|
|
|
|
if(!fname.isEmpty()) {
|
|
// GOT A NAME, APPEND EXTENSION IF NOT GIVEN
|
|
|
|
//if(!fname.endsWith(".nrpb")) fname+=".nrpb";
|
|
|
|
QFile file(fname);
|
|
|
|
if(!file.open(QIODevice::WriteOnly)) {
|
|
QMessageBox a(QMessageBox::Warning, "Error while saving",
|
|
"Cannot write to file " + fname, QMessageBox::Ok, this);
|
|
a.exec();
|
|
return;
|
|
}
|
|
|
|
// FILE IS OPEN AND READY FOR WRITING
|
|
|
|
// STOP RPL ENGINE
|
|
screentmr->stop();
|
|
if(rpl.isRunning()) {
|
|
|
|
setExceptionPoweroff();
|
|
__cpu_idle = 0;
|
|
__pc_terminate = 1;
|
|
__pckeymatrix ^= (1ULL << 63);
|
|
__keyb_update();
|
|
while(rpl.isRunning()) {
|
|
usbupdate();
|
|
__pc_terminate = 1;
|
|
}
|
|
}
|
|
|
|
// PERFORM BACKUP
|
|
myMainWindow = this;
|
|
fileptr = &file;
|
|
rplBackup(&write_data, (void *)fileptr);
|
|
|
|
file.close();
|
|
|
|
__memmap_intact = 2;
|
|
// RESTART RPL ENGINE
|
|
__pc_terminate = 0;
|
|
__pckeymatrix = 0;
|
|
rpl.start();
|
|
screentmr->setSingleShot(true);
|
|
screentmr->start(20);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void MainWindow::on_actionShow_LCD_grid_toggled(bool arg1)
|
|
{
|
|
ui->EmuScreen->BkgndPen.setStyle((arg1) ? Qt::SolidLine : Qt::NoPen);
|
|
|
|
halScreenUpdated();
|
|
|
|
}
|
|
|
|
bool MainWindow::eventFilter(QObject * obj, QEvent * ev)
|
|
{
|
|
if(obj == ui->KeybImage) {
|
|
if((ev->type() == QEvent::TouchBegin)
|
|
|| (ev->type() == QEvent::TouchUpdate)
|
|
|| (ev->type() == QEvent::TouchEnd)
|
|
|| (ev->type() == QEvent::TouchCancel)) {
|
|
// ACCEPT THE TOUCH
|
|
QTouchEvent *me = static_cast < QTouchEvent * >(ev);
|
|
int npoints, k, pressed;
|
|
npoints = me->touchPoints().count();
|
|
for(k = 0; k < npoints; ++k) {
|
|
QPointF coordinates = me->touchPoints().at(k).startPos();
|
|
qreal relx, rely;
|
|
|
|
if(me->touchPoints().at(k).state() & Qt::TouchPointPressed)
|
|
pressed = 1;
|
|
else if(me->touchPoints().at(k).
|
|
state() & Qt::TouchPointReleased)
|
|
pressed = 0;
|
|
else
|
|
continue; // NOT INTERESTED IN DRAGGING
|
|
|
|
relx = coordinates.x() / (qreal) ui->KeybImage->width();
|
|
rely = coordinates.y() / (qreal) ui->KeybImage->height();
|
|
|
|
//qDebug() << "PRESS x=" << relx << ", y=" << rely ;
|
|
|
|
struct mousemap *ptr = mouseMap;
|
|
|
|
while(ptr->key != 0) {
|
|
if((relx >= ptr->left) && (relx <= ptr->right)
|
|
&& (rely >= ptr->top) && (rely <= ptr->bot)) {
|
|
// CLICKED INSIDE A KEY
|
|
|
|
if(ptr->keynum == 64) {
|
|
// PRESSED THE SIMULATED MAIN MENU KEY
|
|
//menuBar()->activateWindow();
|
|
}
|
|
else {
|
|
//TODO: HIGHLIGHT IT FOR VISUAL EFFECT
|
|
if(pressed) {
|
|
__pckeymatrix |= 1ULL << (ptr->keynum);
|
|
//qDebug() << "PRESS x=" << relx << ", y=" << rely << ", key=" << ptr->keynum;
|
|
if(ptr->keynum == 63) {
|
|
// CHECK IF ON WAS PRESSED AND THE CALCULATOR WAS OFF
|
|
if(!rpl.isRunning())
|
|
on_actionPower_ON_triggered();
|
|
}
|
|
}
|
|
else {
|
|
__pckeymatrix &= ~(1ULL << (ptr->keynum));
|
|
//qDebug() << "RELEA x=" << relx << ", y=" << rely << ", key=" << ptr->keynum;
|
|
}
|
|
|
|
__keyb_update();
|
|
}
|
|
}
|
|
ptr++;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if(ev->type() == QEvent::MouseButtonPress) {
|
|
QMouseEvent *me = static_cast < QMouseEvent * >(ev);
|
|
//QPoint coordinates = me->pos();
|
|
qreal relx, rely;
|
|
|
|
/*if(coordinates.y()<30) {
|
|
// TOUCHED THE TOP BAR, SHOW THE MENU
|
|
contextMenuEvent(NULL);
|
|
return true;
|
|
} */
|
|
|
|
relx = (qreal) me->x() / (qreal) ui->KeybImage->width();
|
|
rely = (qreal) me->y() / (qreal) ui->KeybImage->height();
|
|
|
|
//qDebug() << "PRESS x=" << relx << ", y=" << rely ;
|
|
|
|
struct mousemap *ptr = mouseMap;
|
|
|
|
while(ptr->key != 0) {
|
|
if((relx >= ptr->left) && (relx <= ptr->right)
|
|
&& (rely >= ptr->top) && (rely <= ptr->bot)) {
|
|
// CLICKED INSIDE A KEY
|
|
|
|
if(ptr->keynum == 64) {
|
|
// PRESSED THE SIMULATED MAIN MENU KEY
|
|
//menuBar()->activateWindow();
|
|
}
|
|
else {
|
|
//TODO: HIGHLIGHT IT FOR VISUAL EFFECT
|
|
__pckeymatrix |= 1ULL << (ptr->keynum);
|
|
__keyb_update();
|
|
if(ptr->keynum == 63) {
|
|
// CHECK IF ON WAS PRESSED AND THE CALCULATOR WAS OFF
|
|
if(!rpl.isRunning())
|
|
on_actionPower_ON_triggered();
|
|
}
|
|
|
|
}
|
|
}
|
|
ptr++;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
if(ev->type() == QEvent::MouseButtonRelease) {
|
|
QMouseEvent *me = static_cast < QMouseEvent * >(ev);
|
|
//QPoint coordinates = me->pos();
|
|
qreal relx, rely;
|
|
|
|
relx = (qreal) me->x() / (qreal) ui->KeybImage->width();
|
|
rely = (qreal) me->y() / (qreal) ui->KeybImage->height();
|
|
|
|
//qDebug() << "RELEASE x=" << relx << ", y=" << rely ;
|
|
|
|
struct mousemap *ptr = mouseMap;
|
|
|
|
while(ptr->key != 0) {
|
|
if((relx >= ptr->left) && (relx <= ptr->right)
|
|
&& (rely >= ptr->top) && (rely <= ptr->bot)) {
|
|
// CLICKED INSIDE A KEY
|
|
|
|
//TODO: HIGHLIGHT IT FOR VISUAL EFFECT
|
|
__pckeymatrix &= ~(1ULL << (ptr->keynum));
|
|
__keyb_update();
|
|
}
|
|
ptr++;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if(obj == ui->EmuScreen) {
|
|
if((ev->type() == QEvent::TouchBegin)
|
|
|| (ev->type() == QEvent::TouchUpdate)
|
|
|| (ev->type() == QEvent::TouchEnd)
|
|
|| (ev->type() == QEvent::TouchCancel)) {
|
|
// ACCEPT THE TOUCH
|
|
QTouchEvent *me = static_cast < QTouchEvent * >(ev);
|
|
int npoints, k, pressed;
|
|
npoints = me->touchPoints().count();
|
|
for(k = 0; k < npoints; ++k) {
|
|
QPointF coordinates = me->touchPoints().at(k).startPos();
|
|
|
|
if(me->touchPoints().at(k).state() & Qt::TouchPointPressed)
|
|
pressed = 1;
|
|
else if(me->touchPoints().at(k).
|
|
state() & Qt::TouchPointReleased)
|
|
pressed = 0;
|
|
else
|
|
continue; // NOT INTERESTED IN DRAGGING
|
|
|
|
if(pressed && (coordinates.y() < 30)) {
|
|
contextMenuEvent(NULL);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(ev->type() == QEvent::MouseButtonPress) {
|
|
QMouseEvent *me = static_cast < QMouseEvent * >(ev);
|
|
QPoint coordinates = me->pos();
|
|
//qreal relx,rely;
|
|
|
|
if(coordinates.y() < 30) {
|
|
// TOUCHED THE TOP BAR, SHOW THE MENU
|
|
contextMenuEvent(NULL);
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MainWindow::contextMenuEvent(QContextMenuEvent * event)
|
|
{
|
|
QMenu popup;
|
|
popup.addMenu(ui->menuFile);
|
|
popup.addMenu(ui->menuStack);
|
|
popup.addMenu(ui->menuHardware);
|
|
popup.setStyleSheet("font-size: 16px;");
|
|
QString menufilestyle = ui->menuFile->styleSheet();
|
|
ui->menuFile->setStyleSheet("font-size: 16px;");
|
|
QString menustkstyle = ui->menuStack->styleSheet();
|
|
ui->menuStack->setStyleSheet("font-size: 16px;");
|
|
QString menuhardstyle = ui->menuHardware->styleSheet();
|
|
ui->menuHardware->setStyleSheet("font-size: 16px;");
|
|
popup.exec(ui->centralWidget->mapToGlobal(ui->EmuScreen->pos()));
|
|
|
|
ui->menuFile->setStyleSheet(menufilestyle);
|
|
ui->menuStack->setStyleSheet(menustkstyle);
|
|
ui->menuHardware->setStyleSheet(menuhardstyle);
|
|
if(event)
|
|
event->accept();
|
|
}
|
|
|
|
void MainWindow::on_actionPaste_and_compile_triggered()
|
|
{
|
|
if(!rpl.isRunning())
|
|
return; // DO NOTHING
|
|
|
|
while(!__cpu_idle)
|
|
QThread::msleep(1); // BLOCK UNTIL RPL IS IDLE
|
|
|
|
__cpu_idle = 2; // BLOCK REQUEST
|
|
|
|
// NOW WORK ON THE RPL ENGINE WHILE THE THREAD IS BLOCKED
|
|
Clipboard2StackCompile();
|
|
|
|
__cpu_idle = 0; // LET GO THE SIMULATOR
|
|
|
|
halScreenUpdated();
|
|
|
|
}
|
|
|
|
// ****************************************** USB DRIVER ON A SEPARATE THREAD
|
|
|
|
USBThread::USBThread(QObject * parent)
|
|
: QThread(parent)
|
|
{
|
|
}
|
|
|
|
USBThread::~USBThread()
|
|
{
|
|
}
|
|
|
|
// RUNNING THREAD FOR USB COMMS
|
|
// __usb_paused=0 MEANS COMMS ARE ACTIVE
|
|
// __usb_paused==1 MEANS COMMS ARE TEMPORARILY HALTED
|
|
// __usb_paused==2 MEANS EXIT THE THREAD
|
|
|
|
void USBThread::run()
|
|
{
|
|
QElapsedTimer timer;
|
|
timer.start();
|
|
__pcsystmr = timer.elapsed() * 100; // INITIALIZE TICK COUNTER
|
|
__usb_timeout = 5000; // DEFAULT
|
|
|
|
while((__usb_paused != 2) && (__usb_paused != -2)) {
|
|
if(__usb_curdevice && !(__usb_drvstatus & USB_STATUS_CONNECTED))
|
|
usb_irqdisconnect();
|
|
if(__usb_paused == 0)
|
|
usb_irqservice();
|
|
else if(__usb_paused > 0)
|
|
__usb_paused = -__usb_paused; // SIGNAL THAT THE PAUSE WAS ACKNOWLEDGED BY MAKING IT NEGATIVE
|
|
|
|
__pcsystmr = timer.elapsed() * 100;
|
|
|
|
if(__tmr_singleshot_running) {
|
|
if(__tmr1_msec)
|
|
__tmr1_msec--;
|
|
if(!__tmr1_msec) {
|
|
__tmr_singleshot_running = 0;
|
|
__tmr_newirqeventsvc();
|
|
|
|
}
|
|
}
|
|
if(!(__usb_drvstatus & USB_STATUS_NOWAIT))
|
|
msleep(1);
|
|
}
|
|
if(__usb_paused == 2) {
|
|
// EXIT WAS REQUESTED, RELEASE ALL HANDLES
|
|
usb_irqdisconnect();
|
|
|
|
__usb_paused = -__usb_paused; // MAKE SURE WE END THE THREAD WITH A NEGATIVE NUMBER
|
|
}
|
|
}
|
|
|
|
QString MainWindow::getDocumentsLocation()
|
|
{
|
|
QString path;
|
|
|
|
if(currentfile.isEmpty()) {
|
|
path = QStandardPaths::locate(QStandardPaths::DocumentsLocation,
|
|
"newRPL", QStandardPaths::LocateDirectory);
|
|
if(path.isEmpty())
|
|
path = QStandardPaths::writableLocation(QStandardPaths::
|
|
DocumentsLocation);
|
|
}
|
|
else {
|
|
QFileInfo info(currentfile);
|
|
path = info.path();
|
|
}
|
|
|
|
return path;
|
|
}
|
|
|
|
extern "C"
|
|
{
|
|
void usb_mutex_lock_implementation(void);
|
|
void usb_mutex_unlock_implementation(void);
|
|
}
|
|
|
|
static QMutex usb_mutex;
|
|
|
|
void usb_mutex_lock_implementation(void)
|
|
{
|
|
usb_mutex.lock();
|
|
}
|
|
|
|
void usb_mutex_unlock_implementation(void)
|
|
{
|
|
usb_mutex.unlock();
|
|
}
|