1 #include "utils.h"
2 #include "ipc.h"
3 #include "debugger/disasm.h"
4 #include "../../core/cpu.h"
5 #include "../../core/os/os.h"
6 #include "tivarslib/TIVarType.h"
7 #include "tivarslib/TypeHandlers/TypeHandlers.h"
8
9 #include <array>
10
11 #include <QtCore/QDir>
12 #include <QtCore/QString>
13 #include <QtCore/QTime>
14 #include <QtCore/QCoreApplication>
15
16 QString execPath;
17 QString configPath;
18
19 bool guiDebug;
20 bool guiSend;
21 bool guiReceive;
22 bool guiEmuValid = false;
23 bool guiReset = false;
24
isNotValidHex(const std::string & s)25 bool isNotValidHex(const std::string &s) {
26 return s.find_first_not_of("0123456789ABCDEF") != std::string::npos || s.empty();
27 }
28
fileExists(const QString & location)29 bool fileExists(const QString &location) {
30 QString path(location);
31 path = QDir::toNativeSeparators(path);
32
33 if (path.isEmpty()) {
34 return false;
35 }
36
37 if (FILE *file = fopen_utf8(path.toStdString().c_str(), "r")) {
38 fclose(file);
39 return true;
40 } else {
41 return false;
42 }
43 }
44
hex2int(const QString & str)45 int hex2int(const QString &str) {
46 return static_cast<int>(strtol(str.toStdString().c_str(), nullptr, 16));
47 }
48
int2hex(uint32_t a,uint8_t l)49 QString int2hex(uint32_t a, uint8_t l) {
50 return QString::number(a, 16).rightJustified(l, '0', true).toUpper();
51 }
52
calc_var_content_string(const calc_var_t & var)53 std::string calc_var_content_string(const calc_var_t& var) {
54 tivars::stringFromData_handler_t func;
55 // We need to special case some specific temp-equ variables...
56 if (var.type == CALC_VAR_TYPE_EQU && var.name[0] == '$') {
57 func = &tivars::TH_TempEqu::makeStringFromData;
58 } else {
59 func = tivars::TIVarType::createFromID(static_cast<uint>(var.type)).getHandlers().second;
60 }
61 const options_t opts = (calc_var_is_prog(&var) || var.type == CALC_VAR_TYPE_STRING)
62 ? options_t({ {"prettify", true} }) : options_t();
63 return func(data_t(var.data, var.data + var.size), opts);
64 }
65
isRunningInDarkMode()66 bool isRunningInDarkMode() {
67 static bool isDarkMode = false;
68 static bool boolSet = false;
69
70 if (boolSet) {
71 return isDarkMode;
72 }
73
74 // TODO: handle other OS' way to know if we're running in dark mode
75 #if defined(Q_OS_MACX) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_14
76 {
77 std::array<char, 20> buffer;
78 std::string result;
79 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen("defaults read -g AppleInterfaceStyle", "r"), pclose);
80 while (pipe && fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
81 result += buffer.data();
82 }
83 if (result.back() == '\n') {
84 result.pop_back();
85 }
86 isDarkMode = (result == "Dark");
87 }
88 #endif
89
90 boolSet = true;
91
92 return isDarkMode;
93 }
94
95
getAddressOfEquate(const std::string & in)96 QString getAddressOfEquate(const std::string &in) {
97 QString value;
98 map_value_t::const_iterator item = disasm.reverse.find(in);
99 if (item != disasm.reverse.end()) {
100 value = int2hex(item->second, 6);
101 } else {
102 uint32_t conv = 0xFFFFFFFFu;
103 if (in == "AF") {
104 conv = cpu.registers.AF;
105 } else if (in == "HL") {
106 conv = cpu.registers.HL;
107 } else if (in == "DE") {
108 conv = cpu.registers.DE;
109 } else if (in == "BC") {
110 conv = cpu.registers.BC;
111 } else if (in == "IX") {
112 conv = cpu.registers.IX;
113 } else if (in == "IY") {
114 conv = cpu.registers.IY;
115 } else if (in == "AF\'") {
116 conv = cpu.registers._AF;
117 } else if (in == "HL\'") {
118 conv = cpu.registers._HL;
119 } else if (in == "DE\'") {
120 conv = cpu.registers._DE;
121 } else if (in == "BC\'") {
122 conv = cpu.registers._BC;
123 } else if (in == "SPL") {
124 conv = cpu.registers.SPL;
125 } else if (in == "SPS") {
126 conv = cpu.registers.SPS;
127 } else if (in == "PC") {
128 conv = cpu.registers.PC;
129 }
130 if (conv != 0xFFFFFFFFu) {
131 value = int2hex(conv, 6);
132 }
133 }
134 return value;
135 }
136
guiDelay(int ms)137 void guiDelay(int ms) {
138 QTime dt = QTime::currentTime().addMSecs(ms);
139 while (QTime::currentTime() < dt) {
140 qApp->processEvents();
141 }
142 }
143
sendingROM(QDragEnterEvent * e,bool * value)144 QString sendingROM(QDragEnterEvent *e, bool *value) {
145 QString ret;
146 if (value) { *value = false; }
147 if (e->mimeData()->urls().size() == 1) {
148 ret = e->mimeData()->urls().at(0).toLocalFile();
149 if (ret.endsWith(QStringLiteral("rom"), Qt::CaseInsensitive)) {
150 e->accept();
151 if (value) { *value = true; }
152 }
153 }
154 return ret;
155 }
156
157 #ifdef Q_OS_WIN
158 #include <windows.h>
159 #include <tchar.h>
160 #include <psapi.h>
checkProc(DWORD processID)161 static bool checkProc(DWORD processID) {
162 QString processName;
163
164 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
165
166 if (hProcess) {
167 HMODULE hMod;
168 DWORD cbNeeded;
169 wchar_t szProcessName[MAX_PATH];
170
171 if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) {
172 if(GetModuleBaseNameW(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR)) > 0) {
173 processName = QString::fromUtf16((unsigned short*)szProcessName);
174 }
175 }
176 CloseHandle(hProcess);
177 }
178
179 if (!processName.isEmpty()) {
180 return true;
181 }
182
183 return false;
184 }
185 #else
186 #include <sys/types.h>
187 #include <csignal>
checkProc(pid_t pid)188 static bool checkProc(pid_t pid) {
189 if (!kill(pid, 0)) {
190 return true;
191 }
192 return false;
193 }
194 #endif
195
isProcRunning(pid_t procID)196 bool isProcRunning(pid_t procID) {
197 #ifdef Q_OS_WIN
198 return checkProc(static_cast<DWORD>(procID));
199 #else
200 return checkProc(procID);
201 #endif
202 }
203
randomString(const int length)204 QString randomString(const int length) {
205 const QString possibleCharacters(QStringLiteral("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
206
207 QString randomString;
208 for(int i=0; i<length; ++i) {
209 int index = qrand() % possibleCharacters.length();
210 QChar nextChar = possibleCharacters.at(index);
211 randomString.append(nextChar);
212 }
213 return randomString;
214 }
215
appDir()216 QDir appDir() {
217 QDir appDir = qApp->applicationDirPath();
218 #ifdef Q_OS_MACX
219 appDir.cdUp(); // On macOS, the binary is
220 appDir.cdUp(); // actually 3 levels deep
221 appDir.cdUp(); // in the .app folder
222 #endif
223 return appDir;
224 }
225