diff options
Diffstat (limited to 'src/frontend/qt_sdl')
-rw-r--r-- | src/frontend/qt_sdl/CMakeLists.txt | 15 | ||||
-rw-r--r-- | src/frontend/qt_sdl/EmuSettingsDialog.cpp | 7 | ||||
-rw-r--r-- | src/frontend/qt_sdl/InputConfigDialog.cpp | 1 | ||||
-rw-r--r-- | src/frontend/qt_sdl/LAN_PCap.cpp | 21 | ||||
-rw-r--r-- | src/frontend/qt_sdl/Platform.cpp | 47 | ||||
-rw-r--r-- | src/frontend/qt_sdl/PlatformConfig.cpp | 2 | ||||
-rw-r--r-- | src/frontend/qt_sdl/WifiSettingsDialog.cpp | 18 | ||||
-rw-r--r-- | src/frontend/qt_sdl/WifiSettingsDialog.h | 3 | ||||
-rw-r--r-- | src/frontend/qt_sdl/WifiSettingsDialog.ui | 121 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 68 |
10 files changed, 190 insertions, 113 deletions
diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 9a0a025..0d695d6 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -95,6 +95,19 @@ if (PORTABLE) add_definitions(-DPORTABLE) endif() +if (APPLE) + set_target_properties(melonDS PROPERTIES + MACOSX_BUNDLE true + MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/melonDS.plist + OUTPUT_NAME melonDS + ) + + # Copy icon into the bundle + target_sources(melonDS PRIVATE "${CMAKE_SOURCE_DIR}/melonDS.icns") + set_source_files_properties("${CMAKE_SOURCE_DIR}/melonDS.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + +endif() + install(FILES ../../../net.kuribo64.melonDS.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) install(FILES ../../../icon/melon_16x16.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/16x16/apps RENAME net.kuribo64.melonDS.png) install(FILES ../../../icon/melon_32x32.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/32x32/apps RENAME net.kuribo64.melonDS.png) @@ -102,4 +115,4 @@ install(FILES ../../../icon/melon_48x48.png DESTINATION ${CMAKE_INSTALL_PREFIX}/ install(FILES ../../../icon/melon_64x64.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/64x64/apps RENAME net.kuribo64.melonDS.png) install(FILES ../../../icon/melon_128x128.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/128x128/apps RENAME net.kuribo64.melonDS.png) install(FILES ../../../icon/melon_256x256.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps RENAME net.kuribo64.melonDS.png) -install(TARGETS melonDS RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +install(TARGETS melonDS BUNDLE DESTINATION ${CMAKE_BINARY_DIR} RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) diff --git a/src/frontend/qt_sdl/EmuSettingsDialog.cpp b/src/frontend/qt_sdl/EmuSettingsDialog.cpp index 79ce5ed..3183182 100644 --- a/src/frontend/qt_sdl/EmuSettingsDialog.cpp +++ b/src/frontend/qt_sdl/EmuSettingsDialog.cpp @@ -65,6 +65,9 @@ EmuSettingsDialog::EmuSettingsDialog(QWidget* parent) : QDialog(parent), ui(new ui->chkJITBranchOptimisations->setChecked(Config::JIT_BranchOptimisations != 0); ui->chkJITLiteralOptimisations->setChecked(Config::JIT_LiteralOptimisations != 0); ui->chkJITFastMemory->setChecked(Config::JIT_FastMemory != 0); + #ifdef __APPLE__ + ui->chkJITFastMemory->setDisabled(true); + #endif ui->spnJITMaximumBlockSize->setValue(Config::JIT_MaxBlockSize); #else ui->chkEnableJIT->setDisabled(true); @@ -329,6 +332,8 @@ void EmuSettingsDialog::on_chkEnableJIT_toggled() bool disabled = !ui->chkEnableJIT->isChecked(); ui->chkJITBranchOptimisations->setDisabled(disabled); ui->chkJITLiteralOptimisations->setDisabled(disabled); - ui->chkJITFastMemory->setDisabled(disabled); + #ifndef __APPLE__ + ui->chkJITFastMemory->setDisabled(disabled); + #endif ui->spnJITMaximumBlockSize->setDisabled(disabled); } diff --git a/src/frontend/qt_sdl/InputConfigDialog.cpp b/src/frontend/qt_sdl/InputConfigDialog.cpp index 9f08731..eaf1e9b 100644 --- a/src/frontend/qt_sdl/InputConfigDialog.cpp +++ b/src/frontend/qt_sdl/InputConfigDialog.cpp @@ -216,6 +216,7 @@ KeyMapButton::KeyMapButton(int* mapping, bool hotkey) : QPushButton() setCheckable(true); setText(mappingText()); + setFocusPolicy(Qt::StrongFocus); //Fixes binding keys in macOS connect(this, &KeyMapButton::clicked, this, &KeyMapButton::onClick); } diff --git a/src/frontend/qt_sdl/LAN_PCap.cpp b/src/frontend/qt_sdl/LAN_PCap.cpp index ce278bc..3381e80 100644 --- a/src/frontend/qt_sdl/LAN_PCap.cpp +++ b/src/frontend/qt_sdl/LAN_PCap.cpp @@ -33,7 +33,11 @@ #include <sys/types.h> #include <ifaddrs.h> #include <netinet/in.h> - #include <linux/if_packet.h> + #ifdef __linux__ + #include <linux/if_packet.h> + #else + #include <net/if_dl.h> + #endif #endif @@ -66,6 +70,9 @@ const char* PCapLibNames[] = #ifdef __WIN32__ // TODO: name for npcap in non-WinPCap mode "wpcap.dll", +#elif defined(__APPLE__) + "libpcap.A.dylib", + "libpcap.dylib", #else // Linux lib names "libpcap.so.1", @@ -276,6 +283,7 @@ bool Init(bool open_adapter) struct sockaddr_in* sa = (sockaddr_in*)curaddr->ifa_addr; memcpy(adata->IP_v4, &sa->sin_addr, 4); } + #ifdef __linux__ else if (af == AF_PACKET) { struct sockaddr_ll* sa = (sockaddr_ll*)curaddr->ifa_addr; @@ -284,7 +292,16 @@ bool Init(bool open_adapter) else memcpy(adata->MAC, sa->sll_addr, 6); } - + #else + else if (af == AF_LINK) + { + struct sockaddr_dl* sa = (sockaddr_dl*)curaddr->ifa_addr; + if (sa->sdl_alen != 6) + printf("weird MAC length %d for %s\n", sa->sdl_alen, curaddr->ifa_name); + else + memcpy(adata->MAC, LLADDR(sa), 6); + } + #endif curaddr = curaddr->ifa_next; } } diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index a716feb..d3480e4 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -23,6 +23,7 @@ #include <QDir> #include <QThread> #include <QSemaphore> +#include <QMutex> #include <QOpenGLContext> #include "Platform.h" @@ -187,53 +188,77 @@ FILE* OpenLocalFile(const char* path, const char* mode) return OpenFile(fullpath.toUtf8(), mode, mode[0] != 'w'); } -void* Thread_Create(void (* func)()) +Thread* Thread_Create(void (* func)()) { QThread* t = QThread::create(func); t->start(); - return (void*) t; + return (Thread*) t; } -void Thread_Free(void* thread) +void Thread_Free(Thread* thread) { QThread* t = (QThread*) thread; t->terminate(); delete t; } -void Thread_Wait(void* thread) +void Thread_Wait(Thread* thread) { ((QThread*) thread)->wait(); } -void* Semaphore_Create() +Semaphore* Semaphore_Create() { - return new QSemaphore(); + return (Semaphore*)new QSemaphore(); } -void Semaphore_Free(void* sema) +void Semaphore_Free(Semaphore* sema) { delete (QSemaphore*) sema; } -void Semaphore_Reset(void* sema) +void Semaphore_Reset(Semaphore* sema) { QSemaphore* s = (QSemaphore*) sema; s->acquire(s->available()); } -void Semaphore_Wait(void* sema) +void Semaphore_Wait(Semaphore* sema) { ((QSemaphore*) sema)->acquire(); } -void Semaphore_Post(void* sema) +void Semaphore_Post(Semaphore* sema, int count) { - ((QSemaphore*) sema)->release(); + ((QSemaphore*) sema)->release(count); } +Mutex* Mutex_Create() +{ + return (Mutex*)new QMutex(); +} + +void Mutex_Free(Mutex* mutex) +{ + delete (QMutex*) mutex; +} + +void Mutex_Lock(Mutex* mutex) +{ + ((QMutex*) mutex)->lock(); +} + +void Mutex_Unlock(Mutex* mutex) +{ + ((QMutex*) mutex)->unlock(); +} + +bool Mutex_TryLock(Mutex* mutex) +{ + return ((QMutex*) mutex)->try_lock(); +} void* GL_GetProcAddress(const char* proc) { diff --git a/src/frontend/qt_sdl/PlatformConfig.cpp b/src/frontend/qt_sdl/PlatformConfig.cpp index c2d40c4..9861662 100644 --- a/src/frontend/qt_sdl/PlatformConfig.cpp +++ b/src/frontend/qt_sdl/PlatformConfig.cpp @@ -120,7 +120,7 @@ ConfigEntry PlatformConfigFile[] = {"HKJoy_Reset", 0, &HKJoyMapping[HK_Reset], -1, NULL, 0}, {"HKJoy_FastForward", 0, &HKJoyMapping[HK_FastForward], -1, NULL, 0}, {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FastForwardToggle], -1, NULL, 0}, - {"HKJoy_FastForwardToggle", 0, &HKJoyMapping[HK_FullscreenToggle], -1, NULL, 0}, + {"HKJoy_FullscreenToggle", 0, &HKJoyMapping[HK_FullscreenToggle], -1, NULL, 0}, {"HKJoy_SolarSensorDecrease", 0, &HKJoyMapping[HK_SolarSensorDecrease], -1, NULL, 0}, {"HKJoy_SolarSensorIncrease", 0, &HKJoyMapping[HK_SolarSensorIncrease], -1, NULL, 0}, diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.cpp b/src/frontend/qt_sdl/WifiSettingsDialog.cpp index 67297ad..24b339d 100644 --- a/src/frontend/qt_sdl/WifiSettingsDialog.cpp +++ b/src/frontend/qt_sdl/WifiSettingsDialog.cpp @@ -54,7 +54,7 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne LAN_Socket::Init(); haspcap = LAN_PCap::Init(false); - ui->cbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)"); + ui->rbDirectMode->setText("Direct mode (requires " PCAP_NAME " and ethernet connection)"); ui->cbBindAnyAddr->setChecked(Config::SocketBindAnyAddr != 0); ui->cbRandomizeMAC->setChecked(Config::RandomizeMAC != 0); @@ -71,8 +71,9 @@ WifiSettingsDialog::WifiSettingsDialog(QWidget* parent) : QDialog(parent), ui(ne } ui->cbxDirectAdapter->setCurrentIndex(sel); - ui->cbDirectMode->setChecked(Config::DirectLAN != 0); - if (!haspcap) ui->cbDirectMode->setEnabled(false); + ui->rbDirectMode->setChecked(Config::DirectLAN != 0); + ui->rbIndirectMode->setChecked(Config::DirectLAN == 0); + if (!haspcap) ui->rbDirectMode->setEnabled(false); updateAdapterControls(); } @@ -101,7 +102,7 @@ void WifiSettingsDialog::done(int r) Config::SocketBindAnyAddr = ui->cbBindAnyAddr->isChecked() ? 1:0; Config::RandomizeMAC = randommac; - Config::DirectLAN = ui->cbDirectMode->isChecked() ? 1:0; + Config::DirectLAN = ui->rbDirectMode->isChecked() ? 1:0; int sel = ui->cbxDirectAdapter->currentIndex(); if (sel < 0 || sel >= LAN_PCap::NumAdapters) sel = 0; @@ -125,11 +126,14 @@ void WifiSettingsDialog::done(int r) closeDlg(); } -void WifiSettingsDialog::on_cbDirectMode_stateChanged(int state) +void WifiSettingsDialog::on_rbDirectMode_clicked() +{ + updateAdapterControls(); +} +void WifiSettingsDialog::on_rbIndirectMode_clicked() { updateAdapterControls(); } - void WifiSettingsDialog::on_cbxDirectAdapter_currentIndexChanged(int sel) { if (!haspcap) return; @@ -153,7 +157,7 @@ void WifiSettingsDialog::on_cbxDirectAdapter_currentIndexChanged(int sel) void WifiSettingsDialog::updateAdapterControls() { - bool enable = haspcap && ui->cbDirectMode->isChecked(); + bool enable = haspcap && ui->rbDirectMode->isChecked(); ui->cbxDirectAdapter->setEnabled(enable); ui->lblAdapterMAC->setEnabled(enable); diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.h b/src/frontend/qt_sdl/WifiSettingsDialog.h index 6c1f863..600941f 100644 --- a/src/frontend/qt_sdl/WifiSettingsDialog.h +++ b/src/frontend/qt_sdl/WifiSettingsDialog.h @@ -55,7 +55,8 @@ public: private slots: void done(int r); - void on_cbDirectMode_stateChanged(int state); + void on_rbDirectMode_clicked(); + void on_rbIndirectMode_clicked(); void on_cbxDirectAdapter_currentIndexChanged(int sel); private: diff --git a/src/frontend/qt_sdl/WifiSettingsDialog.ui b/src/frontend/qt_sdl/WifiSettingsDialog.ui index 6668d88..174a3dc 100644 --- a/src/frontend/qt_sdl/WifiSettingsDialog.ui +++ b/src/frontend/qt_sdl/WifiSettingsDialog.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>479</width> - <height>240</height> + <width>572</width> + <height>296</height> </rect> </property> <property name="sizePolicy"> @@ -58,67 +58,86 @@ <string>Online</string> </property> <layout class="QGridLayout" name="gridLayout_2"> - <item row="2" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>MAC address:</string> + <item row="3" column="0" rowspan="3" colspan="2"> + <widget class="QGroupBox" name="groupBox_3"> + <property name="title"> + <string>Direct Mode Settings</string> </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Network adapter:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="cbxDirectAdapter"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + <property name="whatsThis"> + <string><html><head/><body><p>Selects the network adapter through which to route network traffic under direct mode.</p></body></html></string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>MAC address:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="lblAdapterMAC"> + <property name="text"> + <string>[PLACEHOLDER]</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>IP address:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="lblAdapterIP"> + <property name="text"> + <string>[PLACEHOLDER]</string> + </property> + </widget> + </item> + </layout> </widget> </item> - <item row="0" column="0" colspan="2"> - <widget class="QCheckBox" name="cbDirectMode"> + <item row="1" column="0"> + <widget class="QRadioButton" name="rbIndirectMode"> <property name="whatsThis"> - <string><html><head/><body><p>Direct mode directly routes network traffic to the host network. It is the most reliable, but requires an ethernet connection.</p><p><br/></p><p>Non-direct mode uses a layer of emulation to get around this, but is more prone to problems.</p></body></html></string> + <string><html><head/><body><p>Indirect mode uses libslirp. It requires no extra setup and is easy to use.</p></body></html></string> </property> <property name="text"> - <string>Direct mode [TEXT PLACEHOLDER]</string> + <string>Indirect Mode (uses libslirp, recommended)</string> </property> </widget> </item> - <item row="1" column="1"> - <widget class="QComboBox" name="cbxDirectAdapter"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>350</width> - <height>0</height> - </size> - </property> + <item row="2" column="0"> + <widget class="QRadioButton" name="rbDirectMode"> <property name="whatsThis"> - <string><html><head/><body><p>Selects the network adapter through which to route network traffic under direct mode.</p></body></html></string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Network adapter:</string> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>IP address:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="lblAdapterMAC"> - <property name="text"> - <string>[PLACEHOLDER]</string> + <string><html><head/><body><p>Direct mode directly routes network traffic to the host network. It is the most reliable, but requires an ethernet connection.</p><p><br/></p><p>Non-direct mode uses a layer of emulation to get around this, but is more prone to problems.</p></body></html></string> </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLabel" name="lblAdapterIP"> <property name="text"> - <string>[PLACEHOLDER]</string> + <string>Direct mode [TEXT PLACEHOLDER]</string> </property> </widget> </item> diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 3a735fb..2d3749d 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -355,10 +355,10 @@ void EmuThread::run() Input::Init(); u32 nframes = 0; - u32 starttick = SDL_GetTicks(); - u32 lasttick = starttick; - u32 lastmeasuretick = lasttick; - u32 fpslimitcount = 0; + double perfCountsSec = 1.0 / SDL_GetPerformanceFrequency(); + double lastTime = SDL_GetPerformanceCounter() * perfCountsSec; + double frameLimitError = 0.0; + double lastMeasureTime = lastTime; char melontitle[100]; @@ -492,49 +492,43 @@ void EmuThread::run() SDL_UnlockMutex(audioSyncLock); } - float framerate = (1000.0f * nlines) / (60.0f * 263.0f); + double frametimeStep = nlines / (60.0 * 263.0); { - u32 curtick = SDL_GetTicks(); - u32 delay = curtick - lasttick; - bool limitfps = Config::LimitFPS && !fastforward; - if (limitfps) - { - float wantedtickF = starttick + (framerate * (fpslimitcount+1)); - u32 wantedtick = (u32)ceil(wantedtickF); - if (curtick < wantedtick) SDL_Delay(wantedtick - curtick); - lasttick = SDL_GetTicks(); - fpslimitcount++; - if ((abs(wantedtickF - (float)wantedtick) < 0.001312) || (fpslimitcount > 60)) - { - fpslimitcount = 0; - starttick = lasttick; - } - } - else + double practicalFramelimit = limitfps ? frametimeStep : 1.0 / 1000.0; + + double curtime = SDL_GetPerformanceCounter() * perfCountsSec; + + frameLimitError += practicalFramelimit - (curtime - lastTime); + if (frameLimitError < -practicalFramelimit) + frameLimitError = -practicalFramelimit; + if (frameLimitError > practicalFramelimit) + frameLimitError = practicalFramelimit; + + if (round(frameLimitError * 1000.0) > 0.0) { - if (delay < 1) SDL_Delay(1); - lasttick = SDL_GetTicks(); + SDL_Delay(round(frameLimitError * 1000.0)); + double timeBeforeSleep = curtime; + curtime = SDL_GetPerformanceCounter() * perfCountsSec; + frameLimitError -= curtime - timeBeforeSleep; } + + lastTime = curtime; } nframes++; if (nframes >= 30) { - u32 tick = SDL_GetTicks(); - u32 diff = tick - lastmeasuretick; - lastmeasuretick = tick; + double time = SDL_GetPerformanceCounter() * perfCountsSec; + double dt = time - lastMeasureTime; + lastMeasureTime = time; - u32 fps; - if (diff < 1) fps = 77777; - else fps = (nframes * 1000) / diff; + u32 fps = round(nframes / dt); nframes = 0; - float fpstarget; - if (framerate < 1) fpstarget = 999; - else fpstarget = 1000.0f/framerate; + float fpstarget = 1.0/frametimeStep; sprintf(melontitle, "[%d/%.0f] melonDS " MELONDS_VERSION, fps, fpstarget); changeWindowTitle(melontitle); @@ -544,10 +538,8 @@ void EmuThread::run() { // paused nframes = 0; - lasttick = SDL_GetTicks(); - starttick = lasttick; - lastmeasuretick = lasttick; - fpslimitcount = 0; + lastTime = SDL_GetPerformanceCounter() * perfCountsSec; + lastMeasureTime = lastTime; emit windowUpdate(); @@ -1354,7 +1346,7 @@ void MainWindow::dragEnterEvent(QDragEnterEvent* event) QString filename = urls.at(0).toLocalFile(); QString ext = filename.right(3); - if (ext == "nds" || ext == "srl" || ext == "dsi" || (ext == "gba" && RunningSomething)) + if (ext == "nds" || ext == "srl" || ext == "dsi" || ext == "gba") event->acceptProposedAction(); } |