CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Qt/mainwindow.cpp
Views: 1401
1
// Qt Desktop UI: works on Linux, Windows and Mac OSX
2
#include "ppsspp_config.h"
3
#include "mainwindow.h"
4
5
#include <QApplication>
6
#include <QDesktopServices>
7
#include <QDesktopWidget>
8
#include <QFile>
9
#include <QFileDialog>
10
#include <QMessageBox>
11
12
#include "Common/System/Display.h"
13
#include "Common/System/NativeApp.h"
14
#include "Common/System/System.h"
15
#include "Common/File/Path.h"
16
#include "Core/MIPS/MIPSDebugInterface.h"
17
#include "Core/Debugger/SymbolMap.h"
18
#include "Core/HLE/sceUmd.h"
19
#include "Core/SaveState.h"
20
#include "Core/System.h"
21
#include "GPU/GPUInterface.h"
22
#include "UI/GamepadEmu.h"
23
24
MainWindow::MainWindow(QWidget *parent, bool fullscreen) :
25
QMainWindow(parent),
26
currentLanguage("en"),
27
nextState(CORE_POWERDOWN),
28
lastUIState(UISTATE_MENU)
29
{
30
#if defined(ASSETS_DIR)
31
if (QFile::exists(ASSETS_DIR "icon_regular_72.png"))
32
setWindowIcon(QIcon(ASSETS_DIR "icon_regular_72.png"));
33
else
34
setWindowIcon(QIcon(qApp->applicationDirPath() + "/assets/icon_regular_72.png"));
35
#else
36
setWindowIcon(QIcon(qApp->applicationDirPath() + "/assets/icon_regular_72.png"));
37
#endif
38
39
SetGameTitle("");
40
emugl = new MainUI(this);
41
42
setCentralWidget(emugl);
43
createMenus();
44
updateMenus();
45
46
SetFullScreen(fullscreen);
47
48
QObject::connect(emugl, SIGNAL(doubleClick()), this, SLOT(fullscrAct()));
49
QObject::connect(emugl, SIGNAL(newFrame()), this, SLOT(newFrame()));
50
}
51
52
inline float clamp1(float x) {
53
if (x > 1.0f) return 1.0f;
54
if (x < -1.0f) return -1.0f;
55
return x;
56
}
57
58
void MainWindow::newFrame()
59
{
60
if (lastUIState != GetUIState()) {
61
lastUIState = GetUIState();
62
if (lastUIState == UISTATE_INGAME && g_Config.UseFullScreen() && !QApplication::overrideCursor() && !g_Config.bShowTouchControls)
63
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
64
if (lastUIState != UISTATE_INGAME && g_Config.UseFullScreen() && QApplication::overrideCursor())
65
QApplication::restoreOverrideCursor();
66
67
updateMenus();
68
}
69
70
if (g_Config.UseFullScreen() != isFullScreen())
71
SetFullScreen(g_Config.UseFullScreen());
72
73
std::unique_lock<std::mutex> lock(msgMutex_);
74
while (!msgQueue_.empty()) {
75
MainWindowMsg msg = msgQueue_.front();
76
msgQueue_.pop();
77
switch (msg) {
78
case MainWindowMsg::BOOT_DONE:
79
bootDone();
80
break;
81
case MainWindowMsg::WINDOW_TITLE_CHANGED:
82
std::unique_lock<std::mutex> lock(titleMutex_);
83
setWindowTitle(QString::fromUtf8(newWindowTitle_.c_str()));
84
break;
85
}
86
}
87
}
88
89
void MainWindow::updateMenuGroupInt(QActionGroup *group, int value) {
90
foreach (QAction *action, group->actions()) {
91
action->setChecked(action->data().toInt() == value);
92
}
93
}
94
95
void MainWindow::updateMenus()
96
{
97
updateMenuGroupInt(saveStateGroup, g_Config.iCurrentStateSlot);
98
updateMenuGroupInt(displayRotationGroup, g_Config.iInternalScreenRotation);
99
updateMenuGroupInt(renderingResolutionGroup, g_Config.iInternalResolution);
100
updateMenuGroupInt(frameSkippingGroup, g_Config.iFrameSkip);
101
updateMenuGroupInt(frameSkippingTypeGroup, g_Config.iFrameSkipType);
102
updateMenuGroupInt(textureFilteringGroup, g_Config.iTexFiltering);
103
updateMenuGroupInt(screenScalingFilterGroup, g_Config.iDisplayFilter);
104
updateMenuGroupInt(textureScalingLevelGroup, g_Config.iTexScalingLevel);
105
updateMenuGroupInt(textureScalingTypeGroup, g_Config.iTexScalingType);
106
107
foreach(QAction * action, windowGroup->actions()) {
108
int width = (g_Config.IsPortrait() ? 272 : 480) * action->data().toInt();
109
int height = (g_Config.IsPortrait() ? 480 : 272) * action->data().toInt();
110
if (g_Config.iWindowWidth == width && g_Config.iWindowHeight == height) {
111
action->setChecked(true);
112
break;
113
}
114
}
115
emit updateMenu();
116
}
117
118
void MainWindow::bootDone()
119
{
120
if (nextState == CORE_RUNNING)
121
runAct();
122
updateMenus();
123
}
124
125
/* SIGNALS */
126
void MainWindow::loadAct()
127
{
128
QString filename = QFileDialog::getOpenFileName(NULL, "Load File", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.chd *.prx)");
129
if (QFile::exists(filename))
130
{
131
QFileInfo info(filename);
132
g_Config.currentDirectory = Path(info.absolutePath().toStdString());
133
System_PostUIMessage(UIMessage::REQUEST_GAME_BOOT, filename.toStdString().c_str());
134
}
135
}
136
137
void MainWindow::closeAct()
138
{
139
updateMenus();
140
141
System_PostUIMessage(UIMessage::REQUEST_GAME_STOP);
142
SetGameTitle("");
143
}
144
145
void MainWindow::openmsAct()
146
{
147
QString confighome = getenv("XDG_CONFIG_HOME");
148
QString memorystick = confighome + "/ppsspp";
149
QDesktopServices::openUrl(QUrl(memorystick));
150
}
151
152
static void SaveStateActionFinished(SaveState::Status status, std::string_view message, void *userdata)
153
{
154
// TODO: Improve messaging?
155
if (status == SaveState::Status::FAILURE)
156
{
157
QMessageBox msgBox;
158
msgBox.setWindowTitle("Load Save State");
159
msgBox.setText("Savestate failure. Please try again later");
160
msgBox.exec();
161
return;
162
}
163
}
164
165
void MainWindow::qlstateAct()
166
{
167
Path gamePath = PSP_CoreParameter().fileToStart;
168
SaveState::LoadSlot(gamePath, 0, SaveStateActionFinished, this);
169
}
170
171
void MainWindow::qsstateAct()
172
{
173
Path gamePath = PSP_CoreParameter().fileToStart;
174
SaveState::SaveSlot(gamePath, 0, SaveStateActionFinished, this);
175
}
176
177
void MainWindow::lstateAct()
178
{
179
QFileDialog dialog(0,"Load state");
180
dialog.setFileMode(QFileDialog::ExistingFile);
181
QStringList filters;
182
filters << "Save States (*.ppst)" << "|All files (*.*)";
183
dialog.setNameFilters(filters);
184
dialog.setAcceptMode(QFileDialog::AcceptOpen);
185
if (dialog.exec())
186
{
187
QStringList fileNames = dialog.selectedFiles();
188
SaveState::Load(Path(fileNames[0].toStdString()), -1, SaveStateActionFinished, this);
189
}
190
}
191
192
void MainWindow::sstateAct()
193
{
194
QFileDialog dialog(0,"Save state");
195
dialog.setFileMode(QFileDialog::AnyFile);
196
dialog.setAcceptMode(QFileDialog::AcceptSave);
197
QStringList filters;
198
filters << "Save States (*.ppst)" << "|All files (*.*)";
199
dialog.setNameFilters(filters);
200
if (dialog.exec())
201
{
202
QStringList fileNames = dialog.selectedFiles();
203
SaveState::Save(Path(fileNames[0].toStdString()), -1, SaveStateActionFinished, this);
204
}
205
}
206
207
void MainWindow::recordDisplayAct()
208
{
209
g_Config.bDumpFrames = !g_Config.bDumpFrames;
210
}
211
212
void MainWindow::useLosslessVideoCodecAct()
213
{
214
g_Config.bUseFFV1 = !g_Config.bUseFFV1;
215
}
216
217
void MainWindow::useOutputBufferAct()
218
{
219
g_Config.bDumpVideoOutput = !g_Config.bDumpVideoOutput;
220
}
221
222
void MainWindow::recordAudioAct()
223
{
224
g_Config.bDumpAudio = !g_Config.bDumpAudio;
225
}
226
227
void MainWindow::exitAct()
228
{
229
closeAct();
230
QApplication::exit(0);
231
}
232
233
void MainWindow::runAct()
234
{
235
System_PostUIMessage(UIMessage::REQUEST_GAME_RUN);
236
}
237
238
void MainWindow::pauseAct()
239
{
240
System_PostUIMessage(UIMessage::REQUEST_GAME_PAUSE);
241
}
242
243
void MainWindow::stopAct()
244
{
245
Core_Stop();
246
System_PostUIMessage(UIMessage::REQUEST_GAME_STOP);
247
}
248
249
void MainWindow::resetAct()
250
{
251
updateMenus();
252
System_PostUIMessage(UIMessage::REQUEST_GAME_RESET);
253
}
254
255
void MainWindow::switchUMDAct()
256
{
257
QString filename = QFileDialog::getOpenFileName(NULL, "Switch UMD", g_Config.currentDirectory.c_str(), "PSP ROMs (*.pbp *.elf *.iso *.cso *.chd *.prx)");
258
if (QFile::exists(filename))
259
{
260
QFileInfo info(filename);
261
g_Config.currentDirectory = Path(info.absolutePath().toStdString());
262
__UmdReplace(Path(filename.toStdString()));
263
}
264
}
265
266
void MainWindow::breakonloadAct()
267
{
268
g_Config.bAutoRun = !g_Config.bAutoRun;
269
}
270
271
void MainWindow::lmapAct()
272
{
273
QFileDialog dialog(0,"Load .MAP");
274
dialog.setFileMode(QFileDialog::ExistingFile);
275
QStringList filters;
276
filters << "Maps (*.map)" << "|All files (*.*)";
277
dialog.setNameFilters(filters);
278
dialog.setAcceptMode(QFileDialog::AcceptOpen);
279
QStringList fileNames;
280
if (dialog.exec())
281
fileNames = dialog.selectedFiles();
282
283
if (fileNames.count() > 0)
284
{
285
QString fileName = QFileInfo(fileNames[0]).absoluteFilePath();
286
g_symbolMap->LoadSymbolMap(Path(fileName.toStdString()));
287
}
288
}
289
290
void MainWindow::smapAct()
291
{
292
QFileDialog dialog(0,"Save .MAP");
293
dialog.setFileMode(QFileDialog::AnyFile);
294
dialog.setAcceptMode(QFileDialog::AcceptSave);
295
QStringList filters;
296
filters << "Save .MAP (*.map)" << "|All files (*.*)";
297
dialog.setNameFilters(filters);
298
QStringList fileNames;
299
if (dialog.exec())
300
{
301
fileNames = dialog.selectedFiles();
302
g_symbolMap->SaveSymbolMap(Path(fileNames[0].toStdString()));
303
}
304
}
305
306
void MainWindow::lsymAct()
307
{
308
QFileDialog dialog(0,"Load .SYM");
309
dialog.setFileMode(QFileDialog::ExistingFile);
310
QStringList filters;
311
filters << "Symbols (*.sym)" << "|All files (*.*)";
312
dialog.setNameFilters(filters);
313
dialog.setAcceptMode(QFileDialog::AcceptOpen);
314
QStringList fileNames;
315
if (dialog.exec())
316
fileNames = dialog.selectedFiles();
317
318
if (fileNames.count() > 0)
319
{
320
QString fileName = QFileInfo(fileNames[0]).absoluteFilePath();
321
g_symbolMap->LoadNocashSym(Path(fileName.toStdString()));
322
}
323
}
324
325
void MainWindow::ssymAct()
326
{
327
QFileDialog dialog(0,"Save .SYM");
328
dialog.setFileMode(QFileDialog::AnyFile);
329
dialog.setAcceptMode(QFileDialog::AcceptSave);
330
QStringList filters;
331
filters << "Save .SYM (*.sym)" << "|All files (*.*)";
332
dialog.setNameFilters(filters);
333
QStringList fileNames;
334
if (dialog.exec())
335
{
336
fileNames = dialog.selectedFiles();
337
g_symbolMap->SaveNocashSym(Path(fileNames[0].toStdString()));
338
}
339
}
340
341
void MainWindow::resetTableAct()
342
{
343
g_symbolMap->Clear();
344
}
345
346
void MainWindow::dumpNextAct()
347
{
348
gpu->DumpNextFrame();
349
}
350
351
void MainWindow::consoleAct()
352
{
353
#if PPSSPP_PLATFORM(WINDOWS)
354
LogManager::GetInstance()->GetConsoleListener()->Show(LogManager::GetInstance()->GetConsoleListener()->Hidden());
355
#endif
356
}
357
358
void MainWindow::raiseTopMost()
359
{
360
setWindowState( (windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
361
raise();
362
activateWindow();
363
}
364
365
void MainWindow::SetFullScreen(bool fullscreen) {
366
if (fullscreen) {
367
#if !PPSSPP_PLATFORM(MAC)
368
menuBar()->hide();
369
370
emugl->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
371
// TODO: Shouldn't this be physicalSize()?
372
emugl->resizeGL(emugl->size().width(), emugl->size().height());
373
// TODO: Won't showFullScreen do this for us?
374
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
375
setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
376
#endif
377
378
showFullScreen();
379
InitPadLayout(g_display.dp_xres, g_display.dp_yres);
380
381
if (GetUIState() == UISTATE_INGAME && !g_Config.bShowTouchControls)
382
QApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
383
} else {
384
#if !PPSSPP_PLATFORM(MAC)
385
menuBar()->show();
386
updateMenus();
387
#endif
388
389
showNormal();
390
SetWindowScale(-1);
391
InitPadLayout(g_display.dp_xres, g_display.dp_yres);
392
393
if (GetUIState() == UISTATE_INGAME && QApplication::overrideCursor())
394
QApplication::restoreOverrideCursor();
395
396
QDesktopWidget *desktop = QApplication::desktop();
397
int screenNum = QProcessEnvironment::systemEnvironment().value("SDL_VIDEO_FULLSCREEN_HEAD", "0").toInt();
398
399
// Move window to the center of selected screen
400
QRect rect = desktop->screenGeometry(screenNum);
401
move((rect.width() - frameGeometry().width()) / 4, (rect.height() - frameGeometry().height()) / 4);
402
}
403
}
404
405
void MainWindow::fullscrAct()
406
{
407
// Toggle the current state.
408
g_Config.bFullScreen = !isFullScreen();
409
g_Config.iForceFullScreen = -1;
410
SetFullScreen(g_Config.bFullScreen);
411
412
QTimer::singleShot(1000, this, SLOT(raiseTopMost()));
413
}
414
415
void MainWindow::websiteAct()
416
{
417
QDesktopServices::openUrl(QUrl("https://www.ppsspp.org/"));
418
}
419
420
void MainWindow::forumAct()
421
{
422
QDesktopServices::openUrl(QUrl("https://forums.ppsspp.org/"));
423
}
424
425
void MainWindow::goldAct()
426
{
427
QDesktopServices::openUrl(QUrl("https://www.ppsspp.org/buygold"));
428
}
429
430
void MainWindow::gitAct()
431
{
432
QDesktopServices::openUrl(QUrl("https://github.com/hrydgard/ppsspp/"));
433
}
434
435
void MainWindow::discordAct()
436
{
437
QDesktopServices::openUrl(QUrl("https://discord.gg/5NJB6dD"));
438
}
439
440
void MainWindow::aboutAct()
441
{
442
QMessageBox::about(this, "About", QString("PPSSPP Qt %1\n\n"
443
"PSP emulator and debugger\n\n"
444
"Copyright (c) by Henrik Rydg\xc3\xa5rd and the PPSSPP Project 2012-\n"
445
"Qt port maintained by xSacha\n\n"
446
"Additional credits:\n"
447
" PSPSDK by #pspdev (freenode)\n"
448
" CISO decompression code by BOOSTER\n"
449
" zlib by Jean-loup Gailly (compression) and Mark Adler (decompression)\n"
450
" Qt project by Digia\n\n"
451
"All trademarks are property of their respective owners.\n"
452
"The emulator is for educational and development purposes only and it may not be used to play games you do not legally own.").arg(PPSSPP_GIT_VERSION));
453
}
454
455
/* Private functions */
456
void MainWindow::SetWindowScale(int zoom) {
457
if (isFullScreen())
458
fullscrAct();
459
460
int width, height;
461
if (zoom == -1 && (g_Config.iWindowWidth <= 0 || g_Config.iWindowHeight <= 0)) {
462
// Default to zoom level 2.
463
zoom = 2;
464
}
465
if (zoom == -1) {
466
// Take the last setting.
467
width = g_Config.iWindowWidth;
468
height = g_Config.iWindowHeight;
469
} else {
470
// Update to the specified factor. Let's clamp first.
471
if (zoom < 1)
472
zoom = 1;
473
if (zoom > 10)
474
zoom = 10;
475
476
width = (g_Config.IsPortrait() ? 272 : 480) * zoom;
477
height = (g_Config.IsPortrait() ? 480 : 272) * zoom;
478
}
479
480
g_Config.iWindowWidth = width;
481
g_Config.iWindowHeight = height;
482
483
#if !PPSSPP_PLATFORM(MAC)
484
emugl->setFixedSize(g_Config.iWindowWidth, g_Config.iWindowHeight);
485
// TODO: Shouldn't this be scaled size?
486
emugl->resizeGL(g_Config.iWindowWidth, g_Config.iWindowHeight);
487
setFixedSize(sizeHint());
488
#else
489
resize(g_Config.iWindowWidth, g_Config.iWindowHeight);
490
#endif
491
updateMenus();
492
}
493
494
void MainWindow::SetGameTitle(QString text)
495
{
496
QString title = QString("PPSSPP %1").arg(PPSSPP_GIT_VERSION);
497
if (text != "")
498
title += QString(" - %1").arg(text);
499
500
setWindowTitle(title);
501
}
502
503
void MainWindow::loadLanguage(const QString& language, bool translate)
504
{
505
if (currentLanguage != language)
506
{
507
QLocale::setDefault(QLocale(language));
508
QApplication::removeTranslator(&translator);
509
510
currentLanguage = language;
511
if (translator.load(QString(":/languages/ppsspp_%1.qm").arg(language))) {
512
QApplication::installTranslator(&translator);
513
}
514
if (translate)
515
emit retranslate();
516
}
517
}
518
519
void MainWindow::createMenus()
520
{
521
// File
522
MenuTree* fileMenu = new MenuTree(this, menuBar(), QT_TR_NOOP("&File"));
523
fileMenu->add(new MenuAction(this, SLOT(loadAct()), QT_TR_NOOP("&Load..."), QKeySequence::Open))
524
->addEnableState(UISTATE_MENU);
525
fileMenu->addSeparator();
526
fileMenu->add(new MenuAction(this, SLOT(openmsAct()), QT_TR_NOOP("Open &Memory Stick")))
527
->addEnableState(UISTATE_MENU);
528
fileMenu->addSeparator();
529
MenuTree* savestateMenu = new MenuTree(this, fileMenu, QT_TR_NOOP("Saves&tate slot"));
530
saveStateGroup = new MenuActionGroup(this, savestateMenu, SLOT(saveStateGroup_triggered(QAction *)),
531
QStringList() << "1" << "2" << "3" << "4" << "5",
532
QList<int>() << 0 << 1 << 2 << 3 << 4);
533
fileMenu->add(new MenuAction(this, SLOT(qlstateAct()), QT_TR_NOOP("L&oad state"), Qt::Key_F4))
534
->addDisableState(UISTATE_MENU);
535
fileMenu->add(new MenuAction(this, SLOT(qsstateAct()), QT_TR_NOOP("S&ave state"), Qt::Key_F2))
536
->addDisableState(UISTATE_MENU);
537
fileMenu->add(new MenuAction(this, SLOT(lstateAct()), QT_TR_NOOP("&Load state file...")))
538
->addDisableState(UISTATE_MENU);
539
fileMenu->add(new MenuAction(this, SLOT(sstateAct()), QT_TR_NOOP("&Save state file...")))
540
->addDisableState(UISTATE_MENU);
541
MenuTree* recordMenu = new MenuTree(this, fileMenu, QT_TR_NOOP("&Record"));
542
recordMenu->add(new MenuAction(this, SLOT(recordDisplayAct()), QT_TR_NOOP("Record &display")))
543
->addEventChecked(&g_Config.bDumpFrames);
544
recordMenu->add(new MenuAction(this, SLOT(useLosslessVideoCodecAct()), QT_TR_NOOP("&Use lossless video codec (FFV1)")))
545
->addEventChecked(&g_Config.bUseFFV1);
546
recordMenu->add(new MenuAction(this, SLOT(useOutputBufferAct()), QT_TR_NOOP("Use output buffer for video")))
547
->addEventChecked(&g_Config.bDumpVideoOutput);
548
recordMenu->addSeparator();
549
recordMenu->add(new MenuAction(this, SLOT(recordAudioAct()), QT_TR_NOOP("Record &audio")))
550
->addEventChecked(&g_Config.bDumpAudio);
551
fileMenu->addSeparator();
552
fileMenu->add(new MenuAction(this, SLOT(exitAct()), QT_TR_NOOP("E&xit"), QKeySequence::Quit));
553
554
// Emulation
555
MenuTree* emuMenu = new MenuTree(this, menuBar(), QT_TR_NOOP("&Emulation"));
556
emuMenu->add(new MenuAction(this, SLOT(pauseAct()), QT_TR_NOOP("&Pause")))
557
->addEnableState(UISTATE_INGAME);
558
emuMenu->add(new MenuAction(this, SLOT(stopAct()), QT_TR_NOOP("&Stop"), Qt::CTRL + Qt::Key_W))
559
->addEnableState(UISTATE_INGAME);
560
emuMenu->add(new MenuAction(this, SLOT(resetAct()), QT_TR_NOOP("R&eset"), Qt::CTRL + Qt::Key_B))
561
->addEnableState(UISTATE_INGAME);
562
emuMenu->add(new MenuAction(this, SLOT(switchUMDAct()), QT_TR_NOOP("Switch UMD"), Qt::CTRL + Qt::Key_U))
563
->addEnableState(UISTATE_INGAME);
564
MenuTree* displayRotationMenu = new MenuTree(this, emuMenu, QT_TR_NOOP("Display rotation"));
565
displayRotationGroup = new MenuActionGroup(this, displayRotationMenu, SLOT(displayRotationGroup_triggered(QAction *)),
566
QStringList() << "Landscape" << "Portrait" << "Landscape reversed" << "Portrait reversed",
567
QList<int>() << 1 << 2 << 3 << 4);
568
569
// Debug
570
MenuTree* debugMenu = new MenuTree(this, menuBar(), QT_TR_NOOP("&Debug"));
571
debugMenu->add(new MenuAction(this, SLOT(breakonloadAct()), QT_TR_NOOP("Break on load")))
572
->addEventUnchecked(&g_Config.bAutoRun);
573
debugMenu->add(new MenuAction(this, SLOT(ignoreIllegalAct()), QT_TR_NOOP("&Ignore illegal reads/writes")))
574
->addEventChecked(&g_Config.bIgnoreBadMemAccess);
575
debugMenu->addSeparator();
576
debugMenu->add(new MenuAction(this, SLOT(lmapAct()), QT_TR_NOOP("&Load MAP file...")))
577
->addDisableState(UISTATE_MENU);
578
debugMenu->add(new MenuAction(this, SLOT(smapAct()), QT_TR_NOOP("&Save MAP file...")))
579
->addDisableState(UISTATE_MENU);
580
debugMenu->add(new MenuAction(this, SLOT(lsymAct()), QT_TR_NOOP("Lo&ad SYM file...")))
581
->addDisableState(UISTATE_MENU);
582
debugMenu->add(new MenuAction(this, SLOT(ssymAct()), QT_TR_NOOP("Sav&e SYM file...")))
583
->addDisableState(UISTATE_MENU);
584
debugMenu->add(new MenuAction(this, SLOT(resetTableAct()),QT_TR_NOOP("Reset s&ymbol table")))
585
->addDisableState(UISTATE_MENU);
586
debugMenu->addSeparator();
587
debugMenu->add(new MenuAction(this, SLOT(takeScreen()), QT_TR_NOOP("&Take screenshot"), Qt::Key_F12))
588
->addDisableState(UISTATE_MENU);
589
debugMenu->add(new MenuAction(this, SLOT(dumpNextAct()), QT_TR_NOOP("D&ump next frame to log")))
590
->addDisableState(UISTATE_MENU);
591
debugMenu->addSeparator();
592
debugMenu->add(new MenuAction(this, SLOT(consoleAct()), QT_TR_NOOP("&Log console"), Qt::CTRL + Qt::Key_L))
593
->addDisableState(UISTATE_MENU);
594
595
// Game settings
596
MenuTree* gameSettingsMenu = new MenuTree(this, menuBar(), QT_TR_NOOP("&Game settings"));
597
gameSettingsMenu->add(new MenuAction(this, SLOT(languageAct()), QT_TR_NOOP("La&nguage...")));
598
gameSettingsMenu->add(new MenuAction(this, SLOT(controlMappingAct()), QT_TR_NOOP("C&ontrol mapping...")));
599
gameSettingsMenu->add(new MenuAction(this, SLOT(displayLayoutEditorAct()), QT_TR_NOOP("Display layout & effects...")));
600
gameSettingsMenu->add(new MenuAction(this, SLOT(moreSettingsAct()), QT_TR_NOOP("&More settings...")));
601
gameSettingsMenu->addSeparator();
602
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
603
gameSettingsMenu->add(new MenuAction(this, SLOT(fullscrAct()), QT_TR_NOOP("&Fullscreen"), Qt::Key_F11))
604
#else
605
gameSettingsMenu->add(new MenuAction(this, SLOT(fullscrAct()), QT_TR_NOOP("Fu&llscreen"), QKeySequence::FullScreen))
606
#endif
607
->addEventChecked(&g_Config.bFullScreen);
608
gameSettingsMenu->add(new MenuAction(this, SLOT(bufferRenderAct()), QT_TR_NOOP("&Skip buffer effects")))
609
->addEventChecked(&g_Config.bSkipBufferEffects);
610
611
MenuTree* renderingResolutionMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("&Rendering resolution"));
612
renderingResolutionGroup = new MenuActionGroup(this, renderingResolutionMenu, SLOT(renderingResolutionGroup_triggered(QAction *)),
613
QStringList() << "&Auto" << "&1x" << "&2x" << "&3x" << "&4x" << "&5x" << "&6x" << "&7x" << "&8x" << "&9x" << "1&0x",
614
QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10);
615
// - Window Size
616
MenuTree* windowMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("&Window size"));
617
windowGroup = new MenuActionGroup(this, windowMenu, SLOT(windowGroup_triggered(QAction *)),
618
QStringList() << "&1x" << "&2x" << "&3x" << "&4x" << "&5x" << "&6x" << "&7x" << "&8x" << "&9x" << "1&0x",
619
QList<int>() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9 << 10);
620
621
MenuTree* frameSkippingMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("&Frame skipping"));
622
frameSkippingMenu->add(new MenuAction(this, SLOT(autoframeskipAct()), QT_TR_NOOP("&Auto")))
623
->addEventChecked(&g_Config.bAutoFrameSkip);
624
frameSkippingMenu->addSeparator();
625
frameSkippingGroup = new MenuActionGroup(this, frameSkippingMenu, SLOT(frameSkippinGroup_triggered(QAction *)),
626
QStringList() << "&Off" << "&1" << "&2" << "&3" << "&4" << "&5" << "&6" << "&7" << "&8",
627
QList<int>() << 0 << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8);
628
MenuTree* frameSkippingTypeMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("Frame skipping type"));
629
frameSkippingTypeGroup = new MenuActionGroup(this, frameSkippingTypeMenu, SLOT(frameSkippingTypeGroup_triggered(QAction *)),
630
QStringList() << "Skip number of frames" << "Skip percent of FPS",
631
QList<int>() << 0 << 1);
632
MenuTree* textureFilteringMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("Te&xture filtering"));
633
textureFilteringGroup = new MenuActionGroup(this, textureFilteringMenu, SLOT(textureFilteringGroup_triggered(QAction *)),
634
QStringList() << "&Auto" << "&Nearest" << "&Linear" << "Auto Max &Quality",
635
QList<int>() << 1 << 2 << 3 << 4);
636
MenuTree* screenScalingFilterMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("Scr&een scaling filter"));
637
screenScalingFilterGroup = new MenuActionGroup(this, screenScalingFilterMenu, SLOT(screenScalingFilterGroup_triggered(QAction *)),
638
QStringList() << "&Linear" << "&Nearest",
639
QList<int>() << 0 << 1);
640
641
MenuTree* textureScalingMenu = new MenuTree(this, gameSettingsMenu, QT_TR_NOOP("&Texture scaling"));
642
textureScalingLevelGroup = new MenuActionGroup(this, textureScalingMenu, SLOT(textureScalingLevelGroup_triggered(QAction *)),
643
QStringList() << "&Off" << "&2x" << "&3x" << "&4x" << "&5x",
644
QList<int>() << 1 << 2 << 3 << 4 << 5);
645
textureScalingMenu->addSeparator();
646
textureScalingTypeGroup = new MenuActionGroup(this, textureScalingMenu, SLOT(textureScalingTypeGroup_triggered(QAction *)),
647
QStringList() << "&xBRZ" << "&Hybrid" << "&Bicubic" << "H&ybrid + bicubic",
648
QList<int>() << 0 << 1 << 2 << 3);
649
textureScalingMenu->addSeparator();
650
textureScalingMenu->add(new MenuAction(this, SLOT(deposterizeAct()), QT_TR_NOOP("&Deposterize")))
651
->addEventChecked(&g_Config.bTexDeposterize);
652
653
gameSettingsMenu->add(new MenuAction(this, SLOT(transformAct()), QT_TR_NOOP("&Hardware transform")))
654
->addEventChecked(&g_Config.bHardwareTransform);
655
gameSettingsMenu->addSeparator();
656
gameSettingsMenu->add(new MenuAction(this, SLOT(audioAct()), QT_TR_NOOP("Enable s&ound")))
657
->addEventChecked(&g_Config.bEnableSound);
658
gameSettingsMenu->addSeparator();
659
gameSettingsMenu->add(new MenuAction(this, SLOT(cheatsAct()), QT_TR_NOOP("Enable &cheats"), Qt::CTRL + Qt::Key_T))
660
->addEventChecked(&g_Config.bEnableCheats);
661
gameSettingsMenu->addSeparator();
662
gameSettingsMenu->add(new MenuAction(this, SLOT(chatAct()), QT_TR_NOOP("Open chat"), Qt::CTRL + Qt::Key_C))
663
->SetEnabledFunc([=]() {
664
return g_Config.bEnableNetworkChat && GetUIState() == UISTATE_INGAME;
665
});
666
667
// Help
668
MenuTree* helpMenu = new MenuTree(this, menuBar(), QT_TR_NOOP("&Help"));
669
helpMenu->add(new MenuAction(this, SLOT(websiteAct()), QT_TR_NOOP("Visit www.&ppsspp.org")));
670
helpMenu->add(new MenuAction(this, SLOT(forumAct()), QT_TR_NOOP("PPSSPP &forums")));
671
helpMenu->add(new MenuAction(this, SLOT(goldAct()), QT_TR_NOOP("Buy &Gold")));
672
helpMenu->add(new MenuAction(this, SLOT(gitAct()), QT_TR_NOOP("Git&Hub")));
673
helpMenu->add(new MenuAction(this, SLOT(discordAct()), QT_TR_NOOP("Discord")));
674
helpMenu->addSeparator();
675
helpMenu->add(new MenuAction(this, SLOT(aboutAct()), QT_TR_NOOP("&About PPSSPP...")));
676
677
retranslate();
678
}
679
680