summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/citra_qt/bootmanager.cpp12
-rw-r--r--src/citra_qt/bootmanager.h6
-rw-r--r--src/core/loader/3dsx.cpp40
-rw-r--r--src/core/loader/3dsx.h14
-rw-r--r--src/core/loader/loader.cpp10
5 files changed, 74 insertions, 8 deletions
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index 7a1360d34..bb9b204f3 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -128,9 +128,6 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) :
BackupGeometry();
-#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
- connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()));
-#endif
}
void GRenderWindow::moveContext()
@@ -278,3 +275,12 @@ void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) {
void GRenderWindow::OnEmulationStopping() {
emu_thread = nullptr;
}
+
+void GRenderWindow::showEvent(QShowEvent * event) {
+ QWidget::showEvent(event);
+
+ // windowHandle() is not initialized until the Window is shown, so we connect it here.
+ #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection);
+ #endif
+}
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h
index dc422358e..2fd611367 100644
--- a/src/citra_qt/bootmanager.h
+++ b/src/citra_qt/bootmanager.h
@@ -123,13 +123,12 @@ public:
void OnClientAreaResized(unsigned width, unsigned height);
- void OnFramebufferSizeChanged();
-
public slots:
void moveContext(); // overridden
void OnEmulationStarting(EmuThread* emu_thread);
void OnEmulationStopping();
+ void OnFramebufferSizeChanged();
signals:
/// Emitted when the window is closed
@@ -146,4 +145,7 @@ private:
int keyboard_id;
EmuThread* emu_thread;
+
+protected:
+ void showEvent(QShowEvent* event) override;
};
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp
index 530837d08..111b6a409 100644
--- a/src/core/loader/3dsx.cpp
+++ b/src/core/loader/3dsx.cpp
@@ -62,6 +62,10 @@ struct THREEDSX_Header
// Sizes of the code, rodata and data segments +
// size of the BSS section (uninitialized latter half of the data segment)
u32 code_seg_size, rodata_seg_size, data_seg_size, bss_size;
+ // offset and size of smdh
+ u32 smdh_offset, smdh_size;
+ // offset to filesystem
+ u32 fs_offset;
};
// Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts.
@@ -267,4 +271,40 @@ ResultStatus AppLoader_THREEDSX::Load() {
return ResultStatus::Success;
}
+ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) {
+ if (!file.IsOpen())
+ return ResultStatus::Error;
+
+ // Reset read pointer in case this file has been read before.
+ file.Seek(0, SEEK_SET);
+
+ THREEDSX_Header hdr;
+ if (file.ReadBytes(&hdr, sizeof(THREEDSX_Header)) != sizeof(THREEDSX_Header))
+ return ResultStatus::Error;
+
+ if (hdr.header_size != sizeof(THREEDSX_Header))
+ return ResultStatus::Error;
+
+ // Check if the 3DSX has a RomFS...
+ if (hdr.fs_offset != 0) {
+ u32 romfs_offset = hdr.fs_offset;
+ u32 romfs_size = file.GetSize() - hdr.fs_offset;
+
+ LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset);
+ LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size);
+
+ // We reopen the file, to allow its position to be independent from file's
+ romfs_file = std::make_shared<FileUtil::IOFile>(filepath, "rb");
+ if (!romfs_file->IsOpen())
+ return ResultStatus::Error;
+
+ offset = romfs_offset;
+ size = romfs_size;
+
+ return ResultStatus::Success;
+ }
+ LOG_DEBUG(Loader, "3DSX has no RomFS");
+ return ResultStatus::ErrorNotUsed;
+}
+
} // namespace Loader
diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h
index a0aa0c533..365ddb7a5 100644
--- a/src/core/loader/3dsx.h
+++ b/src/core/loader/3dsx.h
@@ -17,8 +17,8 @@ namespace Loader {
/// Loads an 3DSX file
class AppLoader_THREEDSX final : public AppLoader {
public:
- AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename)
- : AppLoader(std::move(file)), filename(std::move(filename)) {}
+ AppLoader_THREEDSX(FileUtil::IOFile&& file, std::string filename, const std::string& filepath)
+ : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {}
/**
* Returns the type of the file
@@ -33,8 +33,18 @@ public:
*/
ResultStatus Load() override;
+ /**
+ * Get the RomFS of the application
+ * @param romfs_file Reference to buffer to store data
+ * @param offset Offset in the file to the RomFS
+ * @param size Size of the RomFS in bytes
+ * @return ResultStatus result of function
+ */
+ ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override;
+
private:
std::string filename;
+ std::string filepath;
};
} // namespace Loader
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 74eb6e871..c4b4f5a5d 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -116,7 +116,15 @@ ResultStatus LoadFile(const std::string& filename) {
//3DSX file format...
case FileType::THREEDSX:
- return AppLoader_THREEDSX(std::move(file), filename_filename).Load();
+ {
+ AppLoader_THREEDSX app_loader(std::move(file), filename_filename, filename);
+ // Load application and RomFS
+ if (ResultStatus::Success == app_loader.Load()) {
+ Service::FS::RegisterArchiveType(Common::make_unique<FileSys::ArchiveFactory_RomFS>(app_loader), Service::FS::ArchiveIdCode::RomFS);
+ return ResultStatus::Success;
+ }
+ break;
+ }
// Standard ELF file format...
case FileType::ELF: