From 0009a3ffd193c43b2fbe90789f4e8317d973d60d Mon Sep 17 00:00:00 2001
From: "U-RAYYAN-PC\\Rayyan" <68647953+WaluigiWare64@users.noreply.github.com>
Date: Wed, 22 Jul 2020 15:13:14 +0100
Subject: Add the extractROM function

---
 src/frontend/qt_sdl/main.cpp | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index de6887c..cc541ad 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -21,6 +21,10 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <zip.h>
+#include <fstream>
+#include <iostream>
+
 #include <QApplication>
 #include <QMessageBox>
 #include <QMenuBar>
@@ -1399,6 +1403,41 @@ QString MainWindow::loadErrorStr(int error)
     }
 }
 
+std::string getFileExt(const std::string& s) {
+
+   size_t i = s.rfind('.', s.length());
+   if (i != std::string::npos) {
+      return(s.substr(i+1, s.length() - i));
+   }
+
+   return("");
+}
+std::string extractROM(char* zipName, std::string zipDir){
+    //Open the ZIP archive
+    int err = 0;
+    zip *z = zip_open(zipName, 0, &err);
+    
+	struct zip_stat st;
+    zip_stat_init(&st);
+    zip_stat_index(z, 0, 0, &st); //Get information about the file at index 0
+	
+    //Allocate memory for its uncompressed contents
+    char *contents = new char[st.size];
+	
+    //Read the compressed file
+    zip_file *f = zip_fopen_index(z, 0, 0); //Open file at index 0
+	zip_fread(f, contents, st.size);
+    zip_fclose(f);
+
+    zip_close(z);
+	
+	//Write the file (binary mode)
+    if(!std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write(contents, st.size)) 
+    {
+        std::cerr << "Error writing file" << '\n';
+    }
+	return zipDir + "/" + st.name;
+}
 
 void MainWindow::onOpenFile()
 {
-- 
cgit v1.2.3


From 96e0e371567f90d9a08f1bf7108575fe15f6e1a0 Mon Sep 17 00:00:00 2001
From: "U-RAYYAN-PC\\Rayyan" <68647953+WaluigiWare64@users.noreply.github.com>
Date: Wed, 22 Jul 2020 15:15:56 +0100
Subject: Link it up to onOpenFile()

---
 src/frontend/qt_sdl/main.cpp | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index cc541ad..7dc72de 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1403,15 +1403,6 @@ QString MainWindow::loadErrorStr(int error)
     }
 }
 
-std::string getFileExt(const std::string& s) {
-
-   size_t i = s.rfind('.', s.length());
-   if (i != std::string::npos) {
-      return(s.substr(i+1, s.length() - i));
-   }
-
-   return("");
-}
 std::string extractROM(char* zipName, std::string zipDir){
     //Open the ZIP archive
     int err = 0;
@@ -1432,10 +1423,8 @@ std::string extractROM(char* zipName, std::string zipDir){
     zip_close(z);
 	
 	//Write the file (binary mode)
-    if(!std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write(contents, st.size)) 
-    {
-        std::cerr << "Error writing file" << '\n';
-    }
+    std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write(contents, st.size);
+  
 	return zipDir + "/" + st.name;
 }
 
@@ -1443,11 +1432,23 @@ void MainWindow::onOpenFile()
 {
     emuThread->emuPause();
 
+	bool romExtracted = false; //No use yet but may be useful later
     QString filename = QFileDialog::getOpenFileName(this,
                                                     "Open ROM",
                                                     Config::LastROMFolder,
-                                                    "DS ROMs (*.nds *.dsi *.srl);;GBA ROMs (*.gba);;Any file (*.*)");
-    if (filename.isEmpty())
+                                                    "DS ROMs (*.nds *.dsi *.srl *.zip);;GBA ROMs (*.gba *.zip);;Any file (*.*)");
+    QFileInfo filenameExtLoc = filename;
+
+	if (filenameExtLoc.completeSuffix().toUtf8() == "zip")
+	{
+		printf("Extracting ROM from ZIP...\n");
+		std::string extractRomLoc = extractROM(filename.toUtf8().data(), filenameExtLoc.absolutePath().toUtf8().data());
+		printf("Done.\n");
+		filename = QString::fromUtf8(extractRomLoc.c_str());
+		romExtracted = true;
+	}
+	
+	if (filename.isEmpty())
     {
         emuThread->emuUnpause();
         return;
-- 
cgit v1.2.3


From c8e934ce971ff146a9b076388123dc61f9ad1e9a Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Wed, 22 Jul 2020 16:01:18 +0100
Subject: Fix indentation + delete contents

---
 src/frontend/qt_sdl/main.cpp | 35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 7dc72de..ca8ebc1 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -993,7 +993,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
         QMenu* menu = menubar->addMenu("File");
 
         actOpenROM = menu->addAction("Open ROM...");
-        connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile);
+        connect(actOpenROM, &QAction::triggered, this, &MainWindow::
+	       );
 
         //actBootFirmware = menu->addAction("Launch DS menu");
         actBootFirmware = menu->addAction("Boot firmware");
@@ -1408,7 +1409,7 @@ std::string extractROM(char* zipName, std::string zipDir){
     int err = 0;
     zip *z = zip_open(zipName, 0, &err);
     
-	struct zip_stat st;
+    struct zip_stat st;
     zip_stat_init(&st);
     zip_stat_index(z, 0, 0, &st); //Get information about the file at index 0
 	
@@ -1417,38 +1418,38 @@ std::string extractROM(char* zipName, std::string zipDir){
 	
     //Read the compressed file
     zip_file *f = zip_fopen_index(z, 0, 0); //Open file at index 0
-	zip_fread(f, contents, st.size);
+    zip_fread(f, contents, st.size);
     zip_fclose(f);
 
     zip_close(z);
-	
-	//Write the file (binary mode)
+
+    //Write the file (binary mode)
     std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write(contents, st.size);
-  
-	return zipDir + "/" + st.name;
+    delete[] contents;
+    return zipDir + "/" + st.name;
 }
 
 void MainWindow::onOpenFile()
 {
     emuThread->emuPause();
 
-	bool romExtracted = false; //No use yet but may be useful later
+    bool romExtracted = false; //No use yet but may be useful later
     QString filename = QFileDialog::getOpenFileName(this,
                                                     "Open ROM",
                                                     Config::LastROMFolder,
                                                     "DS ROMs (*.nds *.dsi *.srl *.zip);;GBA ROMs (*.gba *.zip);;Any file (*.*)");
     QFileInfo filenameExtLoc = filename;
 
-	if (filenameExtLoc.completeSuffix().toUtf8() == "zip")
-	{
-		printf("Extracting ROM from ZIP...\n");
-		std::string extractRomLoc = extractROM(filename.toUtf8().data(), filenameExtLoc.absolutePath().toUtf8().data());
-		printf("Done.\n");
-		filename = QString::fromUtf8(extractRomLoc.c_str());
-		romExtracted = true;
-	}
+    if (filenameExtLoc.completeSuffix().toUtf8() == "zip")
+    {
+	    printf("Extracting ROM from ZIP...\n");
+	    std::string extractRomLoc = extractROM(filename.toUtf8().data(), filenameExtLoc.absolutePath().toUtf8().data());
+	    printf("Done.\n");
+	    filename = QString::fromUtf8(extractRomLoc.c_str());
+	    romExtracted = true;
+    }
 	
-	if (filename.isEmpty())
+    if (filename.isEmpty())
     {
         emuThread->emuUnpause();
         return;
-- 
cgit v1.2.3


From 7fb67570e9422b615bbba7f1243b3e0b4bf849e4 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Wed, 22 Jul 2020 16:17:32 +0100
Subject: fix

---
 src/frontend/qt_sdl/main.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index ca8ebc1..75317f8 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -993,8 +993,7 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
         QMenu* menu = menubar->addMenu("File");
 
         actOpenROM = menu->addAction("Open ROM...");
-        connect(actOpenROM, &QAction::triggered, this, &MainWindow::
-	       );
+        connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile);
 
         //actBootFirmware = menu->addAction("Launch DS menu");
         actBootFirmware = menu->addAction("Boot firmware");
-- 
cgit v1.2.3


From 7937406af6c9825bed23f9947f9c0e05d3c4b71e Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Wed, 22 Jul 2020 16:39:24 +0100
Subject: Change binary stream to u8 and cast to char*

---
 src/frontend/qt_sdl/main.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 75317f8..f77c287 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1413,7 +1413,7 @@ std::string extractROM(char* zipName, std::string zipDir){
     zip_stat_index(z, 0, 0, &st); //Get information about the file at index 0
 	
     //Allocate memory for its uncompressed contents
-    char *contents = new char[st.size];
+    u8 *contents = new u8[st.size];
 	
     //Read the compressed file
     zip_file *f = zip_fopen_index(z, 0, 0); //Open file at index 0
@@ -1423,7 +1423,7 @@ std::string extractROM(char* zipName, std::string zipDir){
     zip_close(z);
 
     //Write the file (binary mode)
-    std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write(contents, st.size);
+    std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write((char*) contents, st.size);
     delete[] contents;
     return zipDir + "/" + st.name;
 }
-- 
cgit v1.2.3


From a5d9f6912742b33eab3e9dcee40be72a69cf94bb Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Fri, 24 Jul 2020 18:19:02 +0100
Subject: Fix Linux "invalid encoding" filename

---
 src/frontend/qt_sdl/main.cpp | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index f77c287..c0268bc 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1411,7 +1411,8 @@ std::string extractROM(char* zipName, std::string zipDir){
     struct zip_stat st;
     zip_stat_init(&st);
     zip_stat_index(z, 0, 0, &st); //Get information about the file at index 0
-	
+    char newName[255];
+    strcpy(newName, st.name); //fix for Linux invalid encoding filename	
     //Allocate memory for its uncompressed contents
     u8 *contents = new u8[st.size];
 	
@@ -1423,7 +1424,7 @@ std::string extractROM(char* zipName, std::string zipDir){
     zip_close(z);
 
     //Write the file (binary mode)
-    std::ofstream(zipDir + "/" + st.name, std::ofstream::binary).write((char*) contents, st.size);
+    std::ofstream(zipDir + "/" + newName, std::ofstream::binary).write((char*) contents, st.size);
     delete[] contents;
     return zipDir + "/" + st.name;
 }
@@ -1441,11 +1442,15 @@ void MainWindow::onOpenFile()
 
     if (filenameExtLoc.completeSuffix().toUtf8() == "zip")
     {
-	    printf("Extracting ROM from ZIP...\n");
-	    std::string extractRomLoc = extractROM(filename.toUtf8().data(), filenameExtLoc.absolutePath().toUtf8().data());
-	    printf("Done.\n");
-	    filename = QString::fromUtf8(extractRomLoc.c_str());
-	    romExtracted = true;
+        printf("Extracting ROM from ZIP...\n");
+	std::string extractRomLoc = extractROM(filename.toUtf8().data(), filenameExtLoc.absolutePath().toUtf8().data());
+	printf("Done.\n");
+	filename = QString::fromUtf8(extractRomLoc.c_str());
+	romExtracted = true;
+    } else if (filenameExtLoc.completeSuffix().toUtf8() == "") {
+        //do nothing
+    } else {
+	romExtracted = false;    
     }
 	
     if (filename.isEmpty())
-- 
cgit v1.2.3


From c351e777b443b588bc034546986557f7c0349d84 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Fri, 24 Jul 2020 18:25:07 +0100
Subject: part 2 of fix Linux invalid encoding

---
 src/frontend/qt_sdl/main.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index c0268bc..a867dc6 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1426,7 +1426,7 @@ std::string extractROM(char* zipName, std::string zipDir){
     //Write the file (binary mode)
     std::ofstream(zipDir + "/" + newName, std::ofstream::binary).write((char*) contents, st.size);
     delete[] contents;
-    return zipDir + "/" + st.name;
+    return zipDir + "/" + newName;
 }
 
 void MainWindow::onOpenFile()
-- 
cgit v1.2.3


From 7e5eafe345017dc93a68572528e896f896a6e175 Mon Sep 17 00:00:00 2001
From: "U-RAYYAN-PC\\Rayyan" <68647953+WaluigiWare64@users.noreply.github.com>
Date: Wed, 5 Aug 2020 14:50:18 +0100
Subject: Statically link libzip

---
 src/CMakeLists.txt                 |  6 +++---
 src/frontend/qt_sdl/CMakeLists.txt | 10 ++++++----
 2 files changed, 9 insertions(+), 7 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f1a5a91..491a583 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -93,9 +93,9 @@ if (ENABLE_JIT)
 	endif()
 endif()
 
-find_library(LIBZIP_LIB zip)
+
 if (WIN32)
-	target_link_libraries(core ole32 comctl32 ws2_32 opengl32 ${LIBZIP_LIB})
+	target_link_libraries(core ole32 comctl32 ws2_32 opengl32)
 else()
-	target_link_libraries(core GL EGL ${LIBZIP_LIB})
+	target_link_libraries(core GL EGL)
 endif()
diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index ea7849f..5617f25 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -47,6 +47,7 @@ set(CMAKE_AUTORCC ON)
 find_package(Threads REQUIRED)
 find_package(PkgConfig REQUIRED)
 pkg_check_modules(SDL2 REQUIRED sdl2)
+pkg_check_modules(LIBZIP REQUIRED libzip)
 
 if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL Release))
     add_executable(melonDS WIN32 ${SOURCES_QT_SDL})
@@ -57,15 +58,16 @@ endif()
 target_link_libraries(melonDS ${CMAKE_THREAD_LIBS_INIT})
 
 target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS})
+target_include_directories(melonDS PRIVATE ${LIBZIP_INCLUDE_DIRS})
 target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
 target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
 target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..")
 target_link_libraries(melonDS core)
 
 if (BUILD_STATIC)
-    target_link_libraries(melonDS -static ${SDL2_LIBRARIES})
+    target_link_libraries(melonDS -static ${SDL2_LIBRARIES} ${LIBZIP_STATIC_LIBRARIES})
 else()
-    target_link_libraries(melonDS ${SDL2_LIBRARIES})
+    target_link_libraries(melonDS ${SDL2_LIBRARIES} ${LIBZIP_LIBRARIES})
 endif()
 
 if (UNIX)
@@ -75,9 +77,9 @@ elseif (WIN32)
     option(PORTABLE "Make a portable build that looks for its configuration in the current directory" ON)
     target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc")
 
-    target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32)
+    target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 bcrypt)
     if (BUILD_STATIC)
-        target_link_libraries(melonDS imm32 winmm version setupapi -static Qt5::Core Qt5::Gui Qt5::Widgets z zstd)
+        target_link_libraries(melonDS imm32 winmm version setupapi -static Qt5::Core Qt5::Gui Qt5::Widgets zstd)
     else()
         target_link_libraries(melonDS Qt5::Core Qt5::Gui Qt5::Widgets)
     endif()
-- 
cgit v1.2.3


From 240175f2748e541e158d2b071119050538977b25 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Thu, 6 Aug 2020 14:39:42 +0100
Subject: Update CMakeLists.txt

---
 src/frontend/qt_sdl/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index 20cde39..fcb5c6f 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -84,7 +84,7 @@ elseif (WIN32)
     option(PORTABLE "Make a portable build that looks for its configuration in the current directory" ON)
     target_sources(melonDS PUBLIC "${CMAKE_SOURCE_DIR}/melon.rc")
 
-    target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32 bcrypt)
+    target_link_libraries(melonDS comctl32 d2d1 dwrite uxtheme ws2_32 iphlpapi gdi32)
     if (BUILD_STATIC)
         target_link_libraries(melonDS imm32 winmm version setupapi -static Qt5::Core Qt5::Gui Qt5::Widgets zstd)
     else()
-- 
cgit v1.2.3


From a8851a51f19577f153a3fa5d1021be5794f0921a Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Thu, 22 Oct 2020 23:41:26 +0100
Subject: Switch to libarchive

---
 CMakeLists.txt                      |   2 +-
 src/frontend/qt_sdl/ArchiveUtil.cpp | 101 ++++++++++++++++++++++++++++++++++++
 src/frontend/qt_sdl/ArchiveUtil.h   |  27 ++++++++++
 src/frontend/qt_sdl/CMakeLists.txt  |  11 ++--
 src/frontend/qt_sdl/main.cpp        |  96 ++++++++++++++++++----------------
 5 files changed, 188 insertions(+), 49 deletions(-)
 create mode 100644 src/frontend/qt_sdl/ArchiveUtil.cpp
 create mode 100644 src/frontend/qt_sdl/ArchiveUtil.h

(limited to 'src/frontend/qt_sdl')

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6729e73..4f482d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,7 +5,7 @@ if (POLICY CMP0076)
     cmake_policy(SET CMP0076 NEW)
 endif()
 
-set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD 14)
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
 
 project(melonDS)
diff --git a/src/frontend/qt_sdl/ArchiveUtil.cpp b/src/frontend/qt_sdl/ArchiveUtil.cpp
new file mode 100644
index 0000000..6457b4f
--- /dev/null
+++ b/src/frontend/qt_sdl/ArchiveUtil.cpp
@@ -0,0 +1,101 @@
+/*
+    Copyright 2016-2020 Arisotura, WaluigiWare64
+
+    This file is part of melonDS.
+
+    melonDS is free software: you can redistribute it and/or modify it under
+    the terms of the GNU General Public License as published by the Free
+    Software Foundation, either version 3 of the License, or (at your option)
+    any later version.
+
+    melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+    FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include "ArchiveUtil.h"
+
+namespace Archive
+{
+
+QVector<QString> ListArchive(const char* path)
+{
+    struct archive *a;
+    struct archive_entry *entry;
+    int r;
+
+    QVector<QString> fileList = {"OK"};
+    
+    a = archive_read_new();
+    archive_read_support_filter_all(a);
+    archive_read_support_format_all(a);
+    r = archive_read_open_filename(a, path, 10240);
+    if (r != ARCHIVE_OK)
+    {
+        return QVector<QString> {"Err"};
+    }
+    
+    while (archive_read_next_header(a, &entry) == ARCHIVE_OK) 
+    {
+      fileList.push_back(archive_entry_pathname(entry));
+      archive_read_data_skip(a);
+    }
+    archive_read_close(a);
+    archive_read_free(a);  
+    if (r != ARCHIVE_OK)
+    {
+        return QVector<QString> {"Err"};
+    }
+    
+    return fileList;
+}
+
+QVector<QString> ExtractFileFromArchive(const char* path, const char* wantedFile)
+{
+    struct archive *a = archive_read_new();
+    struct archive_entry *entry;
+    int r;
+
+    archive_read_support_format_all(a);
+    archive_read_support_filter_all(a);
+    
+    r = archive_read_open_filename(a, path, 10240);
+    if (r != ARCHIVE_OK)
+    {
+        return QVector<QString> {"Err"};
+    }
+    while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+        if (wantedFile == nullptr)
+        {
+            break;
+        }
+        if (strcmp(wantedFile, archive_entry_pathname(entry)) == 0)
+        {
+            break;
+        }
+    }
+    size_t bytesToWrite = archive_entry_size(entry);
+    auto archiveBuffer = std::make_unique<u8[]>(bytesToWrite);
+    ssize_t bytesRead = archive_read_data(a, archiveBuffer.get(), bytesToWrite);
+    if (bytesRead < 0)
+    {
+        printf(archive_error_string(a));
+        archiveBuffer.reset(nullptr);
+        return QVector<QString> {"Err", archive_error_string(a)};
+    }
+    
+    const char* fileToWrite = archive_entry_pathname(entry);
+    std::ofstream(fileToWrite, std::ofstream::binary).write((char*)archiveBuffer.get(), bytesToWrite);
+    
+    archiveBuffer.reset(nullptr);
+    archive_read_close(a);
+    archive_read_free(a);
+    return QVector<QString> {QDir::toNativeSeparators(QDir::currentPath() + "/" + fileToWrite)};
+
+}
+
+
+}
diff --git a/src/frontend/qt_sdl/ArchiveUtil.h b/src/frontend/qt_sdl/ArchiveUtil.h
new file mode 100644
index 0000000..5b03a59
--- /dev/null
+++ b/src/frontend/qt_sdl/ArchiveUtil.h
@@ -0,0 +1,27 @@
+#ifndef ARCHIVEUTIL_H
+#define ARCHIVEUTIL_H
+
+#include <stdio.h>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <memory>
+
+#include <QVector>
+#include <QDir>
+
+#include <archive.h>
+#include <archive_entry.h>
+
+#include "types.h"
+
+namespace Archive
+{
+    
+QVector<QString> ListArchive(const char* path);
+QVector<QString> ExtractFileFromArchive(const char* path, const char* wantedFile);
+
+}
+
+#endif // ARCHIVEUTIL_H
diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index fcb5c6f..55b8125 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -16,6 +16,9 @@ SET(SOURCES_QT_SDL
     font.h
     Platform.cpp
     PlatformConfig.cpp
+    
+    ArchiveUtil.h
+    ArchiveUtil.cpp
 
     ../Util_ROM.cpp
     ../Util_Video.cpp
@@ -49,7 +52,7 @@ find_package(PkgConfig REQUIRED)
 find_package(Iconv REQUIRED)
 pkg_check_modules(SDL2 REQUIRED sdl2)
 pkg_check_modules(SLIRP REQUIRED slirp)
-pkg_check_modules(LIBZIP REQUIRED libzip)
+pkg_check_modules(LIBARCHIVE REQUIRED libarchive)
 
 if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL Release))
     add_executable(melonDS WIN32 ${SOURCES_QT_SDL})
@@ -61,16 +64,16 @@ target_link_libraries(melonDS ${CMAKE_THREAD_LIBS_INIT})
 
 target_include_directories(melonDS PRIVATE ${SDL2_INCLUDE_DIRS})
 target_include_directories(melonDS PRIVATE ${SLIRP_INCLUDE_DIRS})
-target_include_directories(melonDS PRIVATE ${LIBZIP_INCLUDE_DIRS})
+target_include_directories(melonDS PRIVATE ${LIBARCHIVE_INCLUDE_DIRS})
 target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
 target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/..")
 target_include_directories(melonDS PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../..")
 target_link_libraries(melonDS core)
 
 if (BUILD_STATIC)
-	target_link_libraries(melonDS -static ${SDL2_STATIC_LIBRARIES} ${SLIRP_STATIC_LIBRARIES} ${LIBZIP_STATIC_LIBRARIES})
+	target_link_libraries(melonDS -static ${SDL2_STATIC_LIBRARIES} ${SLIRP_STATIC_LIBRARIES} ${LIBARCHIVE_STATIC_LIBRARIES})
 else()
-	target_link_libraries(melonDS ${SDL2_LIBRARIES} ${SLIRP_LIBRARIES} ${LIBZIP_LIBRARIES})
+	target_link_libraries(melonDS ${SDL2_LIBRARIES} ${SLIRP_LIBRARIES} ${LIBARCHIVE_LIBRARIES})
 endif()
 
 if (NOT Iconv_IS_BUILT_IN)
diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index c48e506..722ebd5 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -21,18 +21,21 @@
 #include <stdio.h>
 #include <string.h>
 
-#include <zip.h>
-#include <fstream>
-#include <iostream>
+#include <vector>
+#include <string>
+#include <algorithm>
 
 #include <QApplication>
 #include <QMessageBox>
 #include <QMenuBar>
 #include <QFileDialog>
+#include <QInputDialog>
 #include <QPaintEvent>
 #include <QPainter>
 #include <QKeyEvent>
 #include <QMimeData>
+#include <QSet>
+#include <QVector>
 
 #include <SDL2/SDL.h>
 
@@ -64,6 +67,7 @@
 
 #include "main_shaders.h"
 
+#include "ArchiveUtil.h"
 
 // TODO: uniform variable spelling
 
@@ -1416,54 +1420,58 @@ QString MainWindow::loadErrorStr(int error)
     }
 }
 
-std::string extractROM(char* zipName, std::string zipDir){
-    //Open the ZIP archive
-    int err = 0;
-    zip *z = zip_open(zipName, 0, &err);
-    
-    struct zip_stat st;
-    zip_stat_init(&st);
-    zip_stat_index(z, 0, 0, &st); //Get information about the file at index 0
-    char newName[255];
-    strcpy(newName, st.name); //fix for Linux invalid encoding filename	
-    //Allocate memory for its uncompressed contents
-    u8 *contents = new u8[st.size];
-	
-    //Read the compressed file
-    zip_file *f = zip_fopen_index(z, 0, 0); //Open file at index 0
-    zip_fread(f, contents, st.size);
-    zip_fclose(f);
-
-    zip_close(z);
-
-    //Write the file (binary mode)
-    std::ofstream(zipDir + "/" + newName, std::ofstream::binary).write((char*) contents, st.size);
-    delete[] contents;
-    return zipDir + "/" + newName;
-}
-
 void MainWindow::onOpenFile()
 {
     emuThread->emuPause();
 
-    bool romExtracted = false; //No use yet but may be useful later
     QString filename = QFileDialog::getOpenFileName(this,
                                                     "Open ROM",
                                                     Config::LastROMFolder,
-                                                    "DS ROMs (*.nds *.dsi *.srl *.zip);;GBA ROMs (*.gba *.zip);;Any file (*.*)");
-    QFileInfo filenameExtLoc = filename;
-
-    if (filenameExtLoc.completeSuffix().toUtf8() == "zip")
-    {
-        printf("Extracting ROM from ZIP...\n");
-	std::string extractRomLoc = extractROM(filename.toUtf8().data(), filenameExtLoc.absolutePath().toUtf8().data());
-	printf("Done.\n");
-	filename = QString::fromUtf8(extractRomLoc.c_str());
-	romExtracted = true;
-    } else if (filenameExtLoc.completeSuffix().toUtf8() == "") {
-        //do nothing
-    } else {
-	romExtracted = false;    
+                                                    "DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)");
+
+    static const QSet<QString> compressedExts = {"zip", "7z", "rar", "tar", "tar.gz", "tar.xz", "tar.bz2"};
+    if (compressedExts.contains(QFileInfo(filename).completeSuffix()))
+    {
+        printf("Finding list of ROMs...\n");
+        QVector<QString> archiveROMList = Archive::ListArchive(filename.toUtf8().constData());
+        if (archiveROMList.size() > 2)
+        {
+            archiveROMList.removeFirst();
+            QString toLoad = QInputDialog::getItem(this, "melonDS",
+                                      "The archive was found to have multiple files. Select which ROM you want to load.", archiveROMList.toList(), 0, false);
+            printf("Extracting '%s'\n", toLoad.toUtf8().constData());
+            QVector<QString> extractResult = Archive::ExtractFileFromArchive(filename.toUtf8().constData(), toLoad.toUtf8().constData());
+            if (extractResult[0] != QString("Err"))
+            {
+                filename = extractResult[0];
+            }
+            else 
+            {
+                QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
+            }
+        } 
+        else if (archiveROMList.size() == 2)
+        {   
+            printf("Extracting the only ROM in archive\n");
+            QVector<QString> extractResult = Archive::ExtractFileFromArchive(filename.toUtf8().constData(), nullptr);
+            if (extractResult[0] != QString("Err"))
+            {
+                filename = extractResult[0];
+            }
+            else 
+            {
+                QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
+            }
+        }
+        else if ((archiveROMList.size() == 1) && (archiveROMList[0] == QString("OK")))
+        {
+            QMessageBox::warning(this, "melonDS", "The archive is intact, but there are no files inside.");
+        }
+        else
+        {
+            QMessageBox::critical(this, "melonDS", "The archive could not be read. It may be corrupt or you don't have the permissions.");
+        }
+
     }
 	
     if (filename.isEmpty())
-- 
cgit v1.2.3


From d6cade25f4ac6b2ebac9d4830ab7b10294bc4c89 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Sat, 19 Dec 2020 17:41:51 +0000
Subject: Extract ROM to new folder next to archive
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

For example if DS_ROMS.zip had game.nds, the directory structure would be:
├── DS_ROMS
│   └── game.nds
└── DS_ROMS.zip
---
 src/frontend/qt_sdl/ArchiveUtil.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/ArchiveUtil.cpp b/src/frontend/qt_sdl/ArchiveUtil.cpp
index 6457b4f..9885191 100644
--- a/src/frontend/qt_sdl/ArchiveUtil.cpp
+++ b/src/frontend/qt_sdl/ArchiveUtil.cpp
@@ -87,8 +87,9 @@ QVector<QString> ExtractFileFromArchive(const char* path, const char* wantedFile
         return QVector<QString> {"Err", archive_error_string(a)};
     }
     
-    const char* fileToWrite = archive_entry_pathname(entry);
-    std::ofstream(fileToWrite, std::ofstream::binary).write((char*)archiveBuffer.get(), bytesToWrite);
+    QString fileToWrite = QFileInfo(path).absolutePath() + "/" + QFileInfo(dirToWrite).baseName() + "/" + archive_entry_pathname(entry);
+    
+    std::ofstream(fileToWrite.toUtf8().constData(), std::ofstream::binary).write((char*)archiveBuffer.get(), bytesToWrite);
     
     archiveBuffer.reset(nullptr);
     archive_read_close(a);
-- 
cgit v1.2.3


From 0be3f449a778f9f3ce0fd3ef16d4751be01cbbfd Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Sat, 19 Dec 2020 17:46:09 +0000
Subject: fix for the last commit

---
 src/frontend/qt_sdl/ArchiveUtil.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/ArchiveUtil.cpp b/src/frontend/qt_sdl/ArchiveUtil.cpp
index 9885191..e007095 100644
--- a/src/frontend/qt_sdl/ArchiveUtil.cpp
+++ b/src/frontend/qt_sdl/ArchiveUtil.cpp
@@ -87,7 +87,7 @@ QVector<QString> ExtractFileFromArchive(const char* path, const char* wantedFile
         return QVector<QString> {"Err", archive_error_string(a)};
     }
     
-    QString fileToWrite = QFileInfo(path).absolutePath() + "/" + QFileInfo(dirToWrite).baseName() + "/" + archive_entry_pathname(entry);
+    QString fileToWrite = QFileInfo(path).absolutePath() + "/" + QFileInfo(path).baseName() + "/" + archive_entry_pathname(entry);
     
     std::ofstream(fileToWrite.toUtf8().constData(), std::ofstream::binary).write((char*)archiveBuffer.get(), bytesToWrite);
     
-- 
cgit v1.2.3


From 78419dbce1a176ab60bd2f46ba6fb2add180832c Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Sat, 19 Dec 2020 18:17:06 +0000
Subject: Allow pkg-config to find libarchive on macOS

macOS already provides the libarchive libraries, so Homebrew doesn't link it.
However, macOS does not provide the headers.
---
 src/frontend/qt_sdl/CMakeLists.txt | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index 865acca..add53c2 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -53,6 +53,12 @@ find_package(PkgConfig REQUIRED)
 find_package(Iconv REQUIRED)
 pkg_check_modules(SDL2 REQUIRED sdl2)
 pkg_check_modules(SLIRP REQUIRED slirp)
+
+if (APPLE)
+    execute_process(COMMAND brew --prefix libarchive
+                    OUTPUT_VARIABLE LIBARCHIVE_DIR)
+    set(CMAKE_PREFIX_PATH "${LIBARCHIVE_DIR}/lib/pkgconfig")
+endif()
 pkg_check_modules(LIBARCHIVE REQUIRED libarchive)
 
 if (WIN32 AND (CMAKE_BUILD_TYPE STREQUAL Release))
-- 
cgit v1.2.3


From f070eafce473c49979cfe8ec1d2dd65de9084884 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Sun, 3 Jan 2021 15:29:03 +0000
Subject: Fix return value of Archive::ExtractFileFromArchive

---
 src/frontend/qt_sdl/ArchiveUtil.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/ArchiveUtil.cpp b/src/frontend/qt_sdl/ArchiveUtil.cpp
index e007095..f7ca8e6 100644
--- a/src/frontend/qt_sdl/ArchiveUtil.cpp
+++ b/src/frontend/qt_sdl/ArchiveUtil.cpp
@@ -94,7 +94,7 @@ QVector<QString> ExtractFileFromArchive(const char* path, const char* wantedFile
     archiveBuffer.reset(nullptr);
     archive_read_close(a);
     archive_read_free(a);
-    return QVector<QString> {QDir::toNativeSeparators(QDir::currentPath() + "/" + fileToWrite)};
+    return QVector<QString> {fileToWrite};
 
 }
 
-- 
cgit v1.2.3


From 9e15488e95ca6dc2c0dcbd7c4fe77195f5be1b4e Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Sun, 3 Jan 2021 16:00:50 +0000
Subject: Fix mistake in merge commit

---
 src/frontend/qt_sdl/main.cpp | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 91e56f0..1897743 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -1465,21 +1465,6 @@ QString MainWindow::loadErrorStr(int error)
     }
 }
 
-void MainWindow::onOpenFile()
-{
-    emuThread->emuPause();
-
-    QString filename = QFileDialog::getOpenFileName(this,
-                                                    "Open ROM",
-                                                    Config::LastROMFolder,
-                                                    "DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)");
-	
-    if (filename.isEmpty())
-    {
-        emuThread->emuUnpause();
-        return;
-    }
-
 void MainWindow::loadROM(QString filename)
 {
     recentFileList.removeAll(filename);
@@ -1584,7 +1569,7 @@ void MainWindow::onOpenFile()
     QString filename = QFileDialog::getOpenFileName(this,
                                                     "Open ROM",
                                                     Config::LastROMFolder,
-                                                    "DS ROMs (*.nds *.dsi *.srl);;GBA ROMs (*.gba);;Any file (*.*)");
+                                                    "DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)");
     if (filename.isEmpty())
     {
         emuThread->emuUnpause();
-- 
cgit v1.2.3


From 6c911574952eda12dbdeeca04d837af7dc1e2b93 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Mon, 4 Jan 2021 10:31:57 +0000
Subject: Fix libarchive being found on macOS

properly this time
---
 src/frontend/qt_sdl/CMakeLists.txt | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index add53c2..f5fb37a 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -55,8 +55,10 @@ pkg_check_modules(SDL2 REQUIRED sdl2)
 pkg_check_modules(SLIRP REQUIRED slirp)
 
 if (APPLE)
+    # Find libarchive on macOS, because macOS only provides the library, not the headers
     execute_process(COMMAND brew --prefix libarchive
-                    OUTPUT_VARIABLE LIBARCHIVE_DIR)
+                    OUTPUT_VARIABLE LIBARCHIVE_DIR
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
     set(CMAKE_PREFIX_PATH "${LIBARCHIVE_DIR}/lib/pkgconfig")
 endif()
 pkg_check_modules(LIBARCHIVE REQUIRED libarchive)
-- 
cgit v1.2.3


From 00e9a5e0c7afcea3502e8627db7066cc14aa2536 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Tue, 5 Jan 2021 15:34:28 +0000
Subject: Allow melonDS to write the file

The directory wasn't created, so the file was not being written
---
 src/frontend/qt_sdl/ArchiveUtil.cpp | 19 +++++++++++++------
 src/frontend/qt_sdl/ArchiveUtil.h   |  2 --
 2 files changed, 13 insertions(+), 8 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/ArchiveUtil.cpp b/src/frontend/qt_sdl/ArchiveUtil.cpp
index f7ca8e6..ba6e4b6 100644
--- a/src/frontend/qt_sdl/ArchiveUtil.cpp
+++ b/src/frontend/qt_sdl/ArchiveUtil.cpp
@@ -18,6 +18,11 @@
 
 #include "ArchiveUtil.h"
 
+#ifdef _WIN32
+    #include <direct.h>
+    #define mkdir(dir, mode) _mkdir(dir)
+#endif
+
 namespace Archive
 {
 
@@ -86,15 +91,17 @@ QVector<QString> ExtractFileFromArchive(const char* path, const char* wantedFile
         archiveBuffer.reset(nullptr);
         return QVector<QString> {"Err", archive_error_string(a)};
     }
-    
-    QString fileToWrite = QFileInfo(path).absolutePath() + "/" + QFileInfo(path).baseName() + "/" + archive_entry_pathname(entry);
-    
-    std::ofstream(fileToWrite.toUtf8().constData(), std::ofstream::binary).write((char*)archiveBuffer.get(), bytesToWrite);
-    
+    QString nameToWrite = QFileInfo(path).absolutePath() + "/" + QFileInfo(path).baseName() + "/" + archive_entry_pathname(entry);
+
+    mkdir(QFileInfo(path).baseName().toUtf8().constData(), 600); // Create directory otherwise fopen will not open the file
+    FILE* fileToWrite = fopen(nameToWrite.toUtf8().constData(), "wb");
+    fwrite((char*)archiveBuffer.get(), bytesToWrite, 1, fileToWrite);
+    fclose(fileToWrite);
+
     archiveBuffer.reset(nullptr);
     archive_read_close(a);
     archive_read_free(a);
-    return QVector<QString> {fileToWrite};
+    return QVector<QString> {nameToWrite};
 
 }
 
diff --git a/src/frontend/qt_sdl/ArchiveUtil.h b/src/frontend/qt_sdl/ArchiveUtil.h
index 5b03a59..a6f404a 100644
--- a/src/frontend/qt_sdl/ArchiveUtil.h
+++ b/src/frontend/qt_sdl/ArchiveUtil.h
@@ -4,8 +4,6 @@
 #include <stdio.h>
 
 #include <string>
-#include <iostream>
-#include <fstream>
 #include <memory>
 
 #include <QVector>
-- 
cgit v1.2.3


From 8a1f3d8ce2996d1c543da9e9f091d75ca4777454 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Tue, 5 Jan 2021 16:22:07 +0000
Subject: Properly fix macOS finding libarchive

(i hope)
---
 src/frontend/qt_sdl/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt
index f5fb37a..f0362e5 100644
--- a/src/frontend/qt_sdl/CMakeLists.txt
+++ b/src/frontend/qt_sdl/CMakeLists.txt
@@ -59,7 +59,7 @@ if (APPLE)
     execute_process(COMMAND brew --prefix libarchive
                     OUTPUT_VARIABLE LIBARCHIVE_DIR
                     OUTPUT_STRIP_TRAILING_WHITESPACE)
-    set(CMAKE_PREFIX_PATH "${LIBARCHIVE_DIR}/lib/pkgconfig")
+    list(APPEND CMAKE_PREFIX_PATH "${LIBARCHIVE_DIR}")
 endif()
 pkg_check_modules(LIBARCHIVE REQUIRED libarchive)
 
-- 
cgit v1.2.3


From e485ce3e1323205925ce6a5d15c077d29a012302 Mon Sep 17 00:00:00 2001
From: WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com>
Date: Thu, 7 Jan 2021 17:26:55 +0000
Subject: Add Open ROM inside Archive function

instead of using file extensions
---
 src/frontend/qt_sdl/main.cpp | 109 ++++++++++++++++++++++++-------------------
 src/frontend/qt_sdl/main.h   |   2 +
 2 files changed, 63 insertions(+), 48 deletions(-)

(limited to 'src/frontend/qt_sdl')

diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp
index 1897743..1015800 100644
--- a/src/frontend/qt_sdl/main.cpp
+++ b/src/frontend/qt_sdl/main.cpp
@@ -34,7 +34,6 @@
 #include <QPainter>
 #include <QKeyEvent>
 #include <QMimeData>
-#include <QSet>
 #include <QVector>
 
 #include <SDL2/SDL.h>
@@ -1028,6 +1027,9 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
 
         actOpenROM = menu->addAction("Open ROM...");
         connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile);
+        
+        actOpenROMArchive = menu->addAction("Open ROM inside Archive...");
+        connect(actOpenROMArchive, &QAction::triggered, this, &MainWindow::onOpenFileArchive);
 
         recentMenu = menu->addMenu("Open Recent");
         for(int i = 0; i < 10; ++i)
@@ -1470,52 +1472,6 @@ void MainWindow::loadROM(QString filename)
     recentFileList.removeAll(filename);
     recentFileList.prepend(filename);
     updateRecentFilesMenu();
-
-    
-    static const QSet<QString> compressedExts = {"zip", "7z", "rar", "tar", "tar.gz", "tar.xz", "tar.bz2"};
-    if (compressedExts.contains(QFileInfo(filename).completeSuffix()))
-    {
-        printf("Finding list of ROMs...\n");
-        QVector<QString> archiveROMList = Archive::ListArchive(filename.toUtf8().constData());
-        if (archiveROMList.size() > 2)
-        {
-            archiveROMList.removeFirst();
-            QString toLoad = QInputDialog::getItem(this, "melonDS",
-                                      "The archive was found to have multiple files. Select which ROM you want to load.", archiveROMList.toList(), 0, false);
-            printf("Extracting '%s'\n", toLoad.toUtf8().constData());
-            QVector<QString> extractResult = Archive::ExtractFileFromArchive(filename.toUtf8().constData(), toLoad.toUtf8().constData());
-            if (extractResult[0] != QString("Err"))
-            {
-                filename = extractResult[0];
-            }
-            else 
-            {
-                QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
-            }
-        } 
-        else if (archiveROMList.size() == 2)
-        {   
-            printf("Extracting the only ROM in archive\n");
-            QVector<QString> extractResult = Archive::ExtractFileFromArchive(filename.toUtf8().constData(), nullptr);
-            if (extractResult[0] != QString("Err"))
-            {
-                filename = extractResult[0];
-            }
-            else 
-            {
-                QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
-            }
-        }
-        else if ((archiveROMList.size() == 1) && (archiveROMList[0] == QString("OK")))
-        {
-            QMessageBox::warning(this, "melonDS", "The archive is intact, but there are no files inside.");
-        }
-        else
-        {
-            QMessageBox::critical(this, "melonDS", "The archive could not be read. It may be corrupt or you don't have the permissions.");
-        }
-
-    }
   
     // TODO: validate the input file!!
     // * check that it is a proper ROM
@@ -1569,7 +1525,7 @@ void MainWindow::onOpenFile()
     QString filename = QFileDialog::getOpenFileName(this,
                                                     "Open ROM",
                                                     Config::LastROMFolder,
-                                                    "DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)");
+                                                    "DS ROMs (*.nds *.dsi *.srl);;GBA ROMs (*.gba *.zip);;Any file (*.*)");
     if (filename.isEmpty())
     {
         emuThread->emuUnpause();
@@ -1579,6 +1535,63 @@ void MainWindow::onOpenFile()
     loadROM(filename);
 }
 
+void MainWindow::onOpenFileArchive()
+{
+    emuThread->emuPause();
+
+    QString filename = QFileDialog::getOpenFileName(this,
+                                                    "Open ROM Archive",
+                                                    Config::LastROMFolder,
+                                                    "Archived ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *.tar.bz2);;Any file (*.*)");
+    if (filename.isEmpty())
+    {
+        emuThread->emuUnpause();
+        return;
+    }
+
+    printf("Finding list of ROMs...\n");
+    QVector<QString> archiveROMList = Archive::ListArchive(filename.toUtf8().constData());
+    if (archiveROMList.size() > 2)
+    {
+        archiveROMList.removeFirst();
+        QString toLoad = QInputDialog::getItem(this, "melonDS",
+                                  "The archive was found to have multiple files. Select which ROM you want to load.", archiveROMList.toList(), 0, false);
+        printf("Extracting '%s'\n", toLoad.toUtf8().constData());
+        QVector<QString> extractResult = Archive::ExtractFileFromArchive(filename.toUtf8().constData(), toLoad.toUtf8().constData());
+        if (extractResult[0] != QString("Err"))
+        {
+            filename = extractResult[0];
+        }
+        else 
+        {
+            QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
+        }
+    } 
+    else if (archiveROMList.size() == 2)
+    {   
+        printf("Extracting the only ROM in archive\n");
+        QVector<QString> extractResult = Archive::ExtractFileFromArchive(filename.toUtf8().constData(), nullptr);
+        if (extractResult[0] != QString("Err"))
+        {
+            filename = extractResult[0];
+        }
+        else 
+        {
+            QMessageBox::critical(this, "melonDS", QString("There was an error while trying to extract the ROM from the archive: ") + extractResult[1]);
+        }
+    }
+    else if ((archiveROMList.size() == 1) && (archiveROMList[0] == QString("OK")))
+    {
+        QMessageBox::warning(this, "melonDS", "The archive is intact, but there are no files inside.");
+    }
+    else
+    {
+        QMessageBox::critical(this, "melonDS", "The archive could not be read. It may be corrupt or you don't have the permissions.");
+    }
+
+    loadROM(filename);
+}
+
 void MainWindow::onClearRecentFiles()
 {
     recentFileList.clear();
diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h
index d31e706..97f514b 100644
--- a/src/frontend/qt_sdl/main.h
+++ b/src/frontend/qt_sdl/main.h
@@ -191,6 +191,7 @@ signals:
 
 private slots:
     void onOpenFile();
+    void onOpenFileArchive();
     void onClickRecentFile();
     void onClearRecentFiles();
     void onBootFirmware();
@@ -251,6 +252,7 @@ public:
     QWidget* panel;
 
     QAction* actOpenROM;
+    QAction* actOpenROMArchive;
     QAction* actBootFirmware;
     QAction* actSaveState[9];
     QAction* actLoadState[9];
-- 
cgit v1.2.3