mirror of
https://github.com/Luca1991/NDSFactory.git
synced 2025-07-09 13:30:12 +02:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2e129375f9 | ||
|
0ee258df2d | ||
|
82cb6f3108 | ||
|
732a2541ee | ||
|
55fa399dc9 | ||
|
bf4195b581 | ||
|
c916f47f75 | ||
|
11367bfec2 | ||
|
a7537b5515 | ||
|
dec52435c5 | ||
|
4d94a0dc34 | ||
|
8f755e4b65 | ||
|
872514cce5 | ||
|
ac5df00de3 | ||
|
f46e5275d3 | ||
|
e2e53cbed7 | ||
|
c453236abd | ||
|
a2739a9ca8 | ||
|
e17d3805aa | ||
|
099d04d432 | ||
|
dadd1d5c1f | ||
|
ca8ad8259b |
204
.github/workflows/build.yml
vendored
204
.github/workflows/build.yml
vendored
@ -7,124 +7,148 @@ on:
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.7
|
||||
- uses: actions/checkout@v4.1.7
|
||||
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libgl1-mesa-dev and libglvnd-dev cmake qt6-base-dev
|
||||
mkdir build
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential libgl1-mesa-dev libglvnd-dev cmake qt6-base-dev
|
||||
mkdir build
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
make -j4
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
make -j4
|
||||
|
||||
- name: Archive Artifact
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
tar -czvf NDSFactory-${{ github.ref_name }}-Linux-x64.tar.gz NDSFactory ../README.md ../LICENSE
|
||||
- name: Archive Artifact
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
tar -czvf NDSFactory-${{ github.ref_name }}-Linux-x64.tar.gz NDSFactory ../README.md ../LICENSE
|
||||
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: "build/NDSFactory-${{ github.ref_name }}-Linux-x64.tar.gz"
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: "build/NDSFactory-${{ github.ref_name }}-Linux-x64.tar.gz"
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.7
|
||||
- uses: actions/checkout@v4.1.7
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.7.2'
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: "6.7.2"
|
||||
|
||||
- name: Install CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
- name: Install CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
mkdir build
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
mkdir -p build/x86_64 build/arm64 build/universal
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
- name: Configure CMake (x86_64)
|
||||
working-directory: ${{ github.workspace }}/build/x86_64
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 ../..
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
make -j4
|
||||
macdeployqt NDSFactory.app
|
||||
- name: Configure CMake (arm64)
|
||||
working-directory: ${{ github.workspace }}/build/arm64
|
||||
shell: bash
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=arm64 ../..
|
||||
|
||||
- name: Archive Artifact
|
||||
working-directory: ${{github.workspace}}/build
|
||||
shell: bash
|
||||
run: |
|
||||
zip -r NDSFactory-${{ github.ref_name }}-macOS.zip NDSFactory.app ../README.md ../LICENSE
|
||||
- name: Build (x86_64)
|
||||
working-directory: ${{ github.workspace }}/build/x86_64
|
||||
shell: bash
|
||||
run: |
|
||||
make -j4
|
||||
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: "build/NDSFactory-${{ github.ref_name }}-macOS.zip"
|
||||
- name: Build (arm64)
|
||||
working-directory: ${{ github.workspace }}/build/arm64
|
||||
shell: bash
|
||||
run: |
|
||||
make -j4
|
||||
|
||||
- name: Create Universal Binary
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
shell: bash
|
||||
run: |
|
||||
cp -R x86_64/NDSFactory.app universal/
|
||||
lipo -create -output universal/NDSFactory.app/Contents/MacOS/NDSFactory x86_64/NDSFactory.app/Contents/MacOS/NDSFactory arm64/NDSFactory.app/Contents/MacOS/NDSFactory
|
||||
|
||||
- name: Deploy Qt Frameworks
|
||||
working-directory: ${{ github.workspace }}/build/universal
|
||||
shell: bash
|
||||
run: |
|
||||
macdeployqt NDSFactory.app -verbose=1
|
||||
|
||||
- name: Archive Artifact
|
||||
working-directory: ${{ github.workspace }}/build/universal
|
||||
shell: bash
|
||||
run: |
|
||||
zip -r NDSFactory-${{ github.ref_name }}-macOS.zip NDSFactory.app ../README.md ../LICENSE
|
||||
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: "build/universal/NDSFactory-${{ github.ref_name }}-macOS.zip"
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.7
|
||||
- uses: actions/checkout@v4.1.7
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: '6.7.2'
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: "6.7.2"
|
||||
|
||||
- name: Install CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
- name: Install CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
mkdir build
|
||||
- name: Create Build Environment
|
||||
run: |
|
||||
mkdir build
|
||||
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
cmake ..
|
||||
- name: Configure CMake
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
cmake ..
|
||||
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
cmake --build . -j4 --config Release
|
||||
mkdir .\Release\prod
|
||||
move .\Release\NDSFactory.exe .\Release\prod
|
||||
windeployqt .\Release\prod\NDSFactory.exe
|
||||
- name: Build
|
||||
working-directory: ${{github.workspace}}/build
|
||||
run: |
|
||||
cmake --build . -j4 --config Release
|
||||
mkdir .\Release\prod
|
||||
move .\Release\NDSFactory.exe .\Release\prod
|
||||
windeployqt .\Release\prod\NDSFactory.exe
|
||||
|
||||
- name: Archive Artifact
|
||||
working-directory: ${{github.workspace}}/build/Release
|
||||
run: |
|
||||
xcopy ..\..\README.md .\prod
|
||||
xcopy ..\..\LICENSE .\prod
|
||||
powershell "Compress-Archive -Path .\prod\* -DestinationPath .\NDSFactory-${{ github.ref_name }}-Windows-x64.zip"
|
||||
- name: Archive Artifact
|
||||
working-directory: ${{github.workspace}}/build/Release
|
||||
run: |
|
||||
xcopy ..\..\README.md .\prod
|
||||
xcopy ..\..\LICENSE .\prod
|
||||
powershell "Compress-Archive -Path .\prod\* -DestinationPath .\NDSFactory-${{ github.ref_name }}-Windows-x64.zip"
|
||||
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: "build/Release/NDSFactory-${{ github.ref_name }}-Windows-x64.zip"
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v2.0.8
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
files: "build/Release/NDSFactory-${{ github.ref_name }}-Windows-x64.zip"
|
||||
|
@ -84,7 +84,7 @@ else()
|
||||
endif()
|
||||
|
||||
# Set C++ standard for the target
|
||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)
|
||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
|
||||
|
||||
# Enable Qt's automatic features for the target
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
|
22
README.md
22
README.md
@ -39,18 +39,28 @@ In the Unpacker Tab, you can load your Nintendo DS software (.nds) and extract t
|
||||
**You can then do what you want with these sections (inject code, apply patches etc.)**
|
||||
|
||||
## Packer Tab
|
||||
In the Packer Tab, you can recreate a .nds file using your edited sections. If your sections are larger than the originals, you must update their addresses and sizes in the header. Ensure that the addresses do not overlap, or the final ROM will be broken. If you repack edited sections and the FAT files' address is different from the original, you must patch the FAT (fat.bin). The FAT contains absolute addresses representing each file's start and end addresses, so you need to update them accordingly (use the FAT Patching Tab for this).
|
||||
In the Packer Tab, you can recreate a .nds file using your edited sections.
|
||||
If your sections are larger than the originals, you must update their addresses and sizes in the header.
|
||||
Ensure that the addresses do not overlap, or the final ROM will be broken.
|
||||
If you repack edited sections and the FAT files' address is different from the original, you must patch the FAT (fat.bin).
|
||||
The FAT contains absolute addresses representing each file's start and end addresses, so you need to update them accordingly (use the FAT Patching Tab for this).
|
||||
|
||||
WARNING: if the ROM contains ARM9/ARM7 overlays and your sections are larger than the original, you must manually update the overlay offsets in the ovr and fat binaries (using an hex editor).
|
||||
|
||||
## Fat Tools Tab
|
||||
In this tab, you can:
|
||||
* extract the FAT files from fat_data.bin.
|
||||
* patch the FAT section (fat.bin): this is only necessary if the FAT files' final address (fat_data.bin) differs from the original. Patching the FAT is straightforward: load your fat.bin, and fill in the original and new addresses of fat_data.bin. This will produce a patched fat.bin for use in the packing process.
|
||||
* rebuild the FAT files into a new fat.bin and fat_data.bin.
|
||||
If the ROM contains ARM9/ARM7 overlays you must provide the original fat.bin to extract the overlay offsets.
|
||||
|
||||
# Known Limitations/Possible Future Features/Bugs
|
||||
WARNING: DO NOT MODIFY FAT FILES NAMES OR EXTENSIONS, OR YOU WILL NEED A NEW fnt.bin.
|
||||
* patch the FAT section (fat.bin): this is only necessary if the FAT files' final address (fat_data.bin) differs from the original.
|
||||
Patching the FAT is straightforward: load your fat.bin, and fill in the original and new addresses of fat_data.bin. This will produce a patched fat.bin for use in the packing process.
|
||||
|
||||
* Add support to rebuild a new fat_data.bin and fat.bin from a set of files inside a directory.
|
||||
# Credits
|
||||
|
||||
If you find a bug, feel free to open an issue or submit a pull request :)
|
||||
|
||||
### Developed with ❤ by Luca D'Amico
|
||||
### Special thanks to Antonio Barba & Davide Trogu
|
||||
Special thanks to [Antonio Barba](https://github.com/antoniobarba) & [Davide Trogu](https://github.com/Dax89)
|
||||
|
||||
Developed with ❤ by Luca D'Amico
|
||||
|
@ -6,3 +6,8 @@ struct FatRange {
|
||||
uint32_t startAddr;
|
||||
uint32_t endAddr;
|
||||
};
|
||||
|
||||
struct FatFileID {
|
||||
uint16_t id;
|
||||
std::string path;
|
||||
};
|
@ -3,6 +3,7 @@
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include "ndsfactory.h"
|
||||
#include "fatstruct.h"
|
||||
#include "crctable.h"
|
||||
@ -21,94 +22,94 @@
|
||||
#define ROOT_DIRECTORY_ADDRESS 0xF000
|
||||
|
||||
|
||||
NDSFactory::NDSFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool NDSFactory::loadRomHeader(const std::string& romPath, std::vector<char>& romHeader)
|
||||
NFResult NDSFactory::loadRomHeader(const std::string& romPath, std::vector<char>& romHeader)
|
||||
{
|
||||
std::streampos headerSize = sizeof(NDSHeader);
|
||||
std::ifstream romFile (romPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
if (romFile.is_open())
|
||||
{
|
||||
romHeader.resize(static_cast<unsigned long>(headerSize));
|
||||
std::ifstream romFile (romPath, std::ios::binary);
|
||||
if (!romFile.is_open())
|
||||
return NFResult({ false, "Error opening file: " + romPath });
|
||||
|
||||
romFile.seekg (0, std::ios::beg);
|
||||
romFile.read (romHeader.data(), headerSize);
|
||||
romFile.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
romHeader.resize(static_cast<unsigned long>(headerSize));
|
||||
romFile.read (romHeader.data(), headerSize);
|
||||
romFile.close();
|
||||
return NFResult({ true, "" });
|
||||
}
|
||||
|
||||
bool NDSFactory::dumpDataFromFile(const std::string& romPath, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
||||
NFResult NDSFactory::dumpDataFromFile(const std::string& romPath, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ifstream romFile (romPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::ate);
|
||||
if (romFile.is_open() && savedFile.is_open())
|
||||
{
|
||||
std::vector<char> dumpBuffer(size);
|
||||
romFile.seekg (startAddr, std::ios::beg);
|
||||
romFile.read (dumpBuffer.data(), size);
|
||||
romFile.close();
|
||||
std::ifstream romFile (romPath, std::ios::binary);
|
||||
std::ofstream savedFile (savePath, std::ios::binary);
|
||||
if (!romFile.is_open()) return NFResult({ false, "Error opening file: " + romPath });
|
||||
if (!savedFile.is_open()) return NFResult({ false, "Error creating file: " + savePath });
|
||||
|
||||
savedFile.write(dumpBuffer.data(), size);
|
||||
std::vector<char> dumpBuffer(size);
|
||||
romFile.seekg (startAddr, std::ios::beg);
|
||||
romFile.read (dumpBuffer.data(), size);
|
||||
romFile.close();
|
||||
|
||||
savedFile.write(dumpBuffer.data(), size);
|
||||
savedFile.close();
|
||||
return NFResult({ true, "" });
|
||||
}
|
||||
|
||||
bool NDSFactory::logToFile(const std::string& logPath, const std::string& log)
|
||||
{
|
||||
std::ofstream savedFile(logPath, std::ios::out | std::ios::binary | std::ios::app);
|
||||
if (!savedFile.is_open()) return false;
|
||||
|
||||
savedFile.write(log.c_str(), log.size());
|
||||
savedFile.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
NFResult NDSFactory::readBytesFromFile(std::vector<char>& byteBuffer, const std::string& romPath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ifstream romFile (romPath, std::ios::binary);
|
||||
if (!romFile.is_open())
|
||||
return NFResult({ false, "Error opening file: " + romPath });
|
||||
|
||||
romFile.seekg (startAddr, std::ios::beg);
|
||||
romFile.read (byteBuffer.data(), size);
|
||||
romFile.close();
|
||||
return NFResult({ true, "" });
|
||||
}
|
||||
|
||||
NFResult NDSFactory::writeSectionToFile(const std::string& sectionPath, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ifstream sectionFile (sectionPath, std::ios::binary);
|
||||
if (!sectionFile.is_open())
|
||||
return NFResult({ false, "Error opening file: " + sectionPath });
|
||||
|
||||
std::vector<char> dumpBuffer(size);
|
||||
sectionFile.read (dumpBuffer.data(), size);
|
||||
sectionFile.close();
|
||||
return writeBytesToFile(dumpBuffer, savePath, startAddr, size);
|
||||
}
|
||||
|
||||
NFResult NDSFactory::writeBytesToFile(std::vector<char>& byteBuffer, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ofstream savedFile (savePath, std::ios::in | std::ios::out | std::ios::binary);
|
||||
if (!savedFile.is_open())
|
||||
{
|
||||
savedFile.open(savePath, std::ios::out | std::ios::binary);
|
||||
if (!savedFile.is_open()) {
|
||||
return NFResult({ false, "Error creating file: " + savePath });
|
||||
}
|
||||
savedFile.close();
|
||||
return true;
|
||||
savedFile.open(savePath, std::ios::in | std::ios::out | std::ios::binary);
|
||||
if (!savedFile.is_open())
|
||||
return NFResult({ false, "Error opening file: " + savePath });
|
||||
}
|
||||
return false;
|
||||
|
||||
savedFile.seekp(startAddr);
|
||||
savedFile.write(byteBuffer.data(), size);
|
||||
savedFile.close();
|
||||
return NFResult({ true, "" });
|
||||
}
|
||||
|
||||
|
||||
bool NDSFactory::readBytesFromFile(std::vector<char>& byteBuffer, const std::string& romPath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ifstream romFile (romPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
if (romFile.is_open())
|
||||
{
|
||||
romFile.seekg (startAddr, std::ios::beg);
|
||||
romFile.read (byteBuffer.data(), size);
|
||||
romFile.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NDSFactory::writeSectionToFile(const std::string& sectionPath, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ifstream sectionFile (sectionPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::app);
|
||||
if (sectionFile.is_open() && savedFile.is_open())
|
||||
{
|
||||
std::vector<char> dumpBuffer(size);
|
||||
sectionFile.seekg (0, std::ios::beg);
|
||||
sectionFile.read (dumpBuffer.data(), size);
|
||||
sectionFile.close();
|
||||
|
||||
savedFile.seekp(startAddr, std::ios::beg);
|
||||
savedFile.write(dumpBuffer.data(), size);
|
||||
savedFile.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NDSFactory::writeBytesToFile(std::vector<char>& byteBuffer, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
||||
{
|
||||
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::app);
|
||||
if (savedFile.is_open())
|
||||
{
|
||||
savedFile.seekp(startAddr, std::ios::beg);
|
||||
savedFile.write(byteBuffer.data(), size);
|
||||
savedFile.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NDSFactory::writePaddingToFile(char paddingChar, const std::string& filePath, uint32_t startAddr, const uint32_t size)
|
||||
NFResult NDSFactory::writePaddingToFile(char paddingChar, const std::string& filePath, uint32_t startAddr, const uint32_t size)
|
||||
{
|
||||
std::vector<char> paddingBytes(size, paddingChar);
|
||||
return writeBytesToFile(paddingBytes, filePath, startAddr, size);
|
||||
@ -121,7 +122,7 @@ int NDSFactory::getCardSizeInBytes(int cardType)
|
||||
|
||||
bool NDSFactory::checkArm9FooterPresence(const std::string& sectionPath, uint32_t size)
|
||||
{
|
||||
std::ifstream sectionFile (sectionPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
std::ifstream sectionFile (sectionPath, std::ios::binary | std::ios::ate);
|
||||
if (sectionFile.is_open())
|
||||
{
|
||||
std::streamoff sectionRealSize = sectionFile.tellg();
|
||||
@ -134,15 +135,15 @@ bool NDSFactory::checkArm9FooterPresence(const std::string& sectionPath, uint32_
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath)
|
||||
NFResult NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath, bool logFileIDs)
|
||||
{
|
||||
std::vector<char> fatDataBytes;
|
||||
std::vector<char> fatBytes;
|
||||
std::vector<char> fntBytes;
|
||||
|
||||
std::ifstream fatDataSectionFile(fatDataSectionPath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if (!fatDataSectionFile.is_open()) return false;
|
||||
if (!fatDataSectionFile.is_open()) return NFResult({ false, "Error opening file: " + fatDataSectionPath });
|
||||
std::streamoff fatDataSectionSize = fatDataSectionFile.tellg();
|
||||
fatDataBytes.resize(fatDataSectionSize);
|
||||
fatDataSectionFile.seekg(0, std::ios::beg);
|
||||
@ -150,7 +151,7 @@ bool NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std
|
||||
fatDataSectionFile.close();
|
||||
|
||||
std::ifstream fatSectionFile(fatSectionPath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if (!fatSectionFile.is_open()) return false;
|
||||
if (!fatSectionFile.is_open()) return NFResult({ false, "Error opening file: " + fatSectionPath });
|
||||
std::streamoff fatSectionSize = fatSectionFile.tellg();
|
||||
fatBytes.resize(fatSectionSize);
|
||||
fatSectionFile.seekg(0, std::ios::beg);
|
||||
@ -158,7 +159,7 @@ bool NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std
|
||||
fatSectionFile.close();
|
||||
|
||||
std::ifstream fntSectionFile(fntSectionPath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if (!fntSectionFile.is_open()) return false;
|
||||
if (!fntSectionFile.is_open()) return NFResult({ false, "Error opening file: " + fntSectionPath });
|
||||
std::streamoff fntSectionSize = fntSectionFile.tellg();
|
||||
fntBytes.resize(fntSectionSize);
|
||||
fntSectionFile.seekg(0, std::ios::beg);
|
||||
@ -169,7 +170,7 @@ bool NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std
|
||||
|
||||
// This lambda function was written by NyuBlara, all credits to him.
|
||||
// I edited it a bit to make it work with the rest of the updated code.
|
||||
auto parseFolder = [this, fntBytes, pfatrange, fatDataSectionPath, originalFatDataAddr](uint32_t folderId, std::string curPath, auto& parseFolder) {
|
||||
auto parseFolder = [this, fntBytes, pfatrange, fatDataSectionPath, originalFatDataAddr, savePath, logFileIDs](uint32_t folderId, std::string curPath, auto& parseFolder) {
|
||||
|
||||
uint32_t currentOffset = 8 * (folderId & FNT_HEADER_OFFSET_MASK); // offset for the current directory's info in the FNT header
|
||||
// Only the lower 12 bit of the given offset are relevant
|
||||
@ -234,10 +235,16 @@ bool NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std
|
||||
currentOffset += 2;
|
||||
|
||||
if (!std::filesystem::exists(newPath))
|
||||
if (!std::filesystem::create_directory(newPath)) return false;
|
||||
if (!std::filesystem::create_directory(newPath)) return NFResult({ false, "Error creating directory: " + newPath });
|
||||
|
||||
if (logFileIDs)
|
||||
{
|
||||
std::string log = std::format("{:x}",subFolderId) + ":::" + newPath.substr(savePath.size()+1) + '\n';
|
||||
if (!logToFile(savePath + "/_file_IDs.txt", log)) return NFResult({ false, "Error writing to file: " + savePath + "/_file_IDs.txt" });
|
||||
}
|
||||
|
||||
// Jump back to the FNT header and repeat the process for subdirectory !
|
||||
if (!parseFolder(subFolderId, newPath, parseFolder)) return false;
|
||||
if (!parseFolder(subFolderId, newPath, parseFolder).result) return NFResult({ false, "Error parsing folder: " + newPath });
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -247,25 +254,31 @@ bool NDSFactory::extractFatData(const std::string& fatDataSectionPath, const std
|
||||
|
||||
uint32_t fileStartAddr = (pfatrange + fatOffset)->startAddr - originalFatDataAddr;
|
||||
uint32_t fileSize = (pfatrange + fatOffset)->endAddr - (pfatrange + fatOffset)->startAddr;
|
||||
if (!dumpDataFromFile(fatDataSectionPath, newPath, fileStartAddr, fileSize)) return false;
|
||||
if (!dumpDataFromFile(fatDataSectionPath, newPath, fileStartAddr, fileSize).result) return NFResult({ false, "Error dumping file: " + newPath });
|
||||
|
||||
if (logFileIDs)
|
||||
{
|
||||
std::string log = std::format("{:x}", fatOffset) + ":::" + newPath.substr(savePath.size()+1) + '\n';
|
||||
if (!logToFile(savePath + "/_file_IDs.txt", log)) return NFResult({ false, "Error writing to file: " + savePath + "/_file_IDs.txt" });
|
||||
}
|
||||
|
||||
fatOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return NFResult({ true, "" });
|
||||
};
|
||||
|
||||
return parseFolder(ROOT_DIRECTORY_ADDRESS, savePath, parseFolder);
|
||||
}
|
||||
|
||||
bool NDSFactory::patchFat(const std::string& fatSectionPath, uint32_t shiftSize, const std::string& savePath)
|
||||
NFResult NDSFactory::patchFat(const std::string& fatSectionPath, uint32_t shiftSize, const std::string& savePath)
|
||||
{
|
||||
std::vector<char> fatBytes;
|
||||
|
||||
std::ifstream sectionFile (fatSectionPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||
if (!sectionFile.is_open())
|
||||
return false;
|
||||
return { false, "Error opening file: " + fatSectionPath };
|
||||
|
||||
std::streamoff sectionSize = sectionFile.tellg();
|
||||
fatBytes.resize(sectionSize);
|
||||
@ -282,9 +295,97 @@ bool NDSFactory::patchFat(const std::string& fatSectionPath, uint32_t shiftSize,
|
||||
pfatrange->endAddr += shiftSize;
|
||||
}
|
||||
|
||||
std::remove(savePath.c_str());
|
||||
|
||||
return writeBytesToFile(fatBytes, savePath, 0, static_cast<uint32_t>(sectionSize));
|
||||
}
|
||||
|
||||
NFResult NDSFactory::buildFatData(const std::string& fatDataDirPath, const std::string& originalFatPath, uint32_t fatDataAddr, const std::string& savePath)
|
||||
{
|
||||
std::vector<char> fatDataBytes;
|
||||
std::vector<FatRange> fat;
|
||||
std::vector<char> fntBytes;
|
||||
|
||||
std::vector<FatFileID> fileIDs;
|
||||
std::ifstream fileIDsFile(fatDataDirPath + "/_file_IDs.txt", std::ios::in);
|
||||
if (!fileIDsFile.is_open()) return { false, "Error opening file: " + fatDataDirPath + "/_file_IDs.txt" };
|
||||
std::string fileIDsLine;
|
||||
while (std::getline(fileIDsFile, fileIDsLine))
|
||||
{
|
||||
FatFileID fatFileID;
|
||||
fatFileID.id = static_cast<uint16_t>(std::stoi(fileIDsLine.substr(0, fileIDsLine.find(":::")), nullptr, 16));
|
||||
fatFileID.path = fileIDsLine.substr(fileIDsLine.find(":::") + 3);
|
||||
fileIDs.push_back(fatFileID);
|
||||
}
|
||||
fileIDsFile.close();
|
||||
|
||||
// This loop is needed to detect if roms has overlay files
|
||||
// and if so, we need to extract their addresses from the original fat.bin
|
||||
// it is a hacky but it works
|
||||
for (FatFileID fatFileID : fileIDs)
|
||||
{
|
||||
std::string currentFile = fatDataDirPath + "/" + fatFileID.path;
|
||||
if (std::filesystem::is_directory(std::filesystem::path(currentFile))) continue;
|
||||
|
||||
int firstFileId = fatFileID.id;
|
||||
if (firstFileId > 0)
|
||||
{
|
||||
std::ifstream originalFatFile(originalFatPath, std::ios::in | std::ios::binary);
|
||||
if (!originalFatFile.is_open()) return { false, "Error opening file: " + originalFatPath };
|
||||
std::vector<char> ovrBytes;
|
||||
uint32_t requiredBytes = firstFileId * sizeof(FatRange);
|
||||
ovrBytes.resize(requiredBytes);
|
||||
originalFatFile.read(ovrBytes.data(), requiredBytes);
|
||||
originalFatFile.close();
|
||||
|
||||
FatRange* pfatrange = reinterpret_cast<FatRange*>(ovrBytes.data());
|
||||
for (size_t i = 0; i < ovrBytes.size(); i += sizeof(FatRange), pfatrange++)
|
||||
fat.push_back({ pfatrange->startAddr, pfatrange->endAddr });
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (FatFileID fatFileID : fileIDs)
|
||||
{
|
||||
std::string currentFile = fatDataDirPath + "/" + fatFileID.path;
|
||||
|
||||
if (std::filesystem::is_directory(std::filesystem::path(currentFile))) continue;
|
||||
|
||||
FatRange fatRange;
|
||||
fatRange.startAddr = fatDataAddr + static_cast<uint32_t>(fatDataBytes.size());
|
||||
|
||||
std::ifstream currentFatDataFile(currentFile, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
if (!currentFatDataFile.is_open()) return NFResult({ false, "Error opening file: " + currentFile });
|
||||
std::streamsize size = currentFatDataFile.tellg();
|
||||
currentFatDataFile.seekg(0, std::ios::beg);
|
||||
|
||||
std::vector<char> buffer(size);
|
||||
if (currentFatDataFile.read(buffer.data(), size))
|
||||
fatDataBytes.insert(fatDataBytes.end(), buffer.begin(), buffer.end());
|
||||
else
|
||||
{
|
||||
currentFatDataFile.close();
|
||||
return NFResult({ false, "Error reading file: " + currentFile });
|
||||
}
|
||||
currentFatDataFile.close();
|
||||
|
||||
fatRange.endAddr = fatDataAddr + static_cast<uint32_t>(fatDataBytes.size());
|
||||
fat.push_back(fatRange);
|
||||
}
|
||||
|
||||
|
||||
const char* fat_ptr = reinterpret_cast<const char*>(fat.data());
|
||||
std::vector<char> fatBytes(fat_ptr, fat_ptr + fat.size() * sizeof(FatRange));
|
||||
std::remove((savePath + "/fat_data.bin").c_str());
|
||||
std::remove((savePath + "/fat.bin").c_str());
|
||||
if (!writeBytesToFile(fatDataBytes, savePath + "/fat_data.bin", 0, static_cast<uint32_t>(fatDataBytes.size())).result)
|
||||
return NFResult({ false, "Error writing to file: " + savePath + "/fat_data.bin" });
|
||||
if (!writeBytesToFile(fatBytes, savePath + "/fat.bin", 0, static_cast<uint32_t>(fatBytes.size())).result)
|
||||
return NFResult({ false, "Error writing to file: " + savePath + "/fat.bin" });
|
||||
|
||||
return NFResult({ true, "" });
|
||||
}
|
||||
|
||||
uint16_t NDSFactory::calcHeaderCrc16(const std::vector<char>& romHeader)
|
||||
{
|
||||
uint8_t loc;
|
||||
|
@ -5,27 +5,28 @@
|
||||
#include <cstdint>
|
||||
#include "ndsheader.h"
|
||||
#include "fatstruct.h"
|
||||
|
||||
#include "nfresult.h"
|
||||
|
||||
|
||||
class NDSFactory
|
||||
{
|
||||
public:
|
||||
NDSFactory();
|
||||
bool loadRomHeader(const std::string& romPath, std::vector<char>& header);
|
||||
bool dumpDataFromFile(const std::string& romPath, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
bool readBytesFromFile(std::vector<char>& byteBuffer, const std::string& romPath, uint32_t startAddr, uint32_t size);
|
||||
bool writeSectionToFile(const std::string& sectionPath, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
bool writeBytesToFile(std::vector<char>& byteBuffer, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
bool writePaddingToFile(char paddingChar, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
NFResult loadRomHeader(const std::string& romPath, std::vector<char>& header);
|
||||
NFResult dumpDataFromFile(const std::string& romPath, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
NFResult readBytesFromFile(std::vector<char>& byteBuffer, const std::string& romPath, uint32_t startAddr, uint32_t size);
|
||||
NFResult writeSectionToFile(const std::string& sectionPath, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
NFResult writeBytesToFile(std::vector<char>& byteBuffer, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
NFResult writePaddingToFile(char paddingChar, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||
int getCardSizeInBytes(int cardType);
|
||||
bool checkArm9FooterPresence(const std::string& sectionPath, uint32_t size);
|
||||
bool extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath);
|
||||
bool patchFat(const std::string& sectionPath, uint32_t shiftSize, const std::string& savePath);
|
||||
NFResult extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath, bool logFileIDs);
|
||||
NFResult patchFat(const std::string& sectionPath, uint32_t shiftSize, const std::string& savePath);
|
||||
NFResult buildFatData(const std::string& fatDataDirPath, const std::string& originalFatPath, uint32_t fatDataAddr, const std::string& savePath);
|
||||
uint16_t calcHeaderCrc16(const std::vector<char>& romHeader);
|
||||
|
||||
private:
|
||||
bool logToFile(const std::string& logPath, const std::string& log);
|
||||
|
||||
};
|
||||
|
||||
|
9
ndsfactory/nfresult.h
Normal file
9
ndsfactory/nfresult.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct NFResult
|
||||
{
|
||||
bool result;
|
||||
std::string message;
|
||||
};
|
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 45 KiB |
@ -42,7 +42,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>NDS Factory V1.2</string>
|
||||
<string>NDSFactory V1.3.2</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
@ -58,7 +58,7 @@
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(C) 2019-2024 - Luca D'Amico</string>
|
||||
<string>(C) 2019-2025 - Luca D'Amico</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||
|
@ -1,6 +1,6 @@
|
||||
#ifndef REVISION_H
|
||||
#define REVISION_H
|
||||
|
||||
#define GIT_COMMIT_HASH "e788d95"
|
||||
#define GIT_COMMIT_HASH "c916f47"
|
||||
|
||||
#endif
|
||||
|
@ -58,6 +58,9 @@ private slots:
|
||||
void on_fatExtractorLoadFatBtn_clicked();
|
||||
void on_fatExtractorLoadFntBtn_clicked();
|
||||
void on_fatExtractorExtractBtn_clicked();
|
||||
void on_fatBuilderOpenFatDataDirBtn_clicked();
|
||||
void on_fatBuilderLoadOriginalFatBtn_clicked();
|
||||
void on_fatBuilderBuildBtn_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
@ -66,48 +69,48 @@ private:
|
||||
void populateHeader(NDSHeader* ndsHeader);
|
||||
void enableExtractionButtons();
|
||||
void disableExtractionButtons();
|
||||
bool dumpHeader(const std::string& dirPath);
|
||||
bool dumpArm9Bin(const std::string& dirPath, bool dumpExtraBytes);
|
||||
bool dumpArm7Bin(const std::string& dirPath);
|
||||
bool dumpFnt(const std::string& dirPath);
|
||||
bool dumpFat(const std::string& dirPath);
|
||||
bool dumpArm9Overlay(const std::string& dirPath);
|
||||
bool dumpArm9OverlayFiles(const std::string& dirPath);
|
||||
bool dumpArm7Overlay(const std::string& dirPath);
|
||||
bool dumpArm7OverlayFiles(const std::string& dirPath);
|
||||
bool dumpIconTitle(const std::string& dirPath);
|
||||
bool dumpFatFiles(const std::string& dirPath);
|
||||
bool dumpEverything(QString dirPath);
|
||||
void notifyExtractionResult(bool result);
|
||||
NFResult dumpHeader(const std::string& dirPath);
|
||||
NFResult dumpArm9Bin(const std::string& dirPath, bool dumpExtraBytes);
|
||||
NFResult dumpArm7Bin(const std::string& dirPath);
|
||||
NFResult dumpFnt(const std::string& dirPath);
|
||||
NFResult dumpFat(const std::string& dirPath);
|
||||
NFResult dumpArm9Overlay(const std::string& dirPath);
|
||||
NFResult dumpArm9OverlayFiles(const std::string& dirPath);
|
||||
NFResult dumpArm7Overlay(const std::string& dirPath);
|
||||
NFResult dumpArm7OverlayFiles(const std::string& dirPath);
|
||||
NFResult dumpIconTitle(const std::string& dirPath);
|
||||
NFResult dumpFatFiles(const std::string& dirPath);
|
||||
NFResult dumpEverything(QString dirPath);
|
||||
|
||||
void populatePackerSectionHeader(NDSHeader *ndsHeader);
|
||||
void enableCalcCrcButton();
|
||||
void enableBuildRomButton();
|
||||
void generateHeader(NDSHeader* pRomHeader);
|
||||
bool writeHeader(const std::string& savePath);
|
||||
NFResult writeHeader(const std::string& savePath);
|
||||
void calcHeaderCrc16();
|
||||
bool writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent);
|
||||
bool writeArm7Bin(const std::string& savePath);
|
||||
bool writeFnt(const std::string& savePath);
|
||||
bool writeFat(const std::string& savePath);
|
||||
bool writeArm9Overlay(const std::string& savePath);
|
||||
bool writeArm9OverlayFiles(const std::string& savePath);
|
||||
bool writeArm7Overlay(const std::string& savePath);
|
||||
bool writeArm7OverlayFiles(const std::string& savePath);
|
||||
bool writeIconTitle(const std::string& savePath);
|
||||
bool writeFatFiles(const std::string& savePath);
|
||||
bool writeEverything(const std::string& savePath);
|
||||
NFResult writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent);
|
||||
NFResult writeArm7Bin(const std::string& savePath);
|
||||
NFResult writeFnt(const std::string& savePath);
|
||||
NFResult writeFat(const std::string& savePath);
|
||||
NFResult writeArm9Overlay(const std::string& savePath);
|
||||
NFResult writeArm9OverlayFiles(const std::string& savePath);
|
||||
NFResult writeArm7Overlay(const std::string& savePath);
|
||||
NFResult writeArm7OverlayFiles(const std::string& savePath);
|
||||
NFResult writeIconTitle(const std::string& savePath);
|
||||
NFResult writeFatFiles(const std::string& savePath);
|
||||
NFResult writeEverything(const std::string& savePath);
|
||||
|
||||
bool writeHeaderPadding(char paddingByte, const std::string& savePath);
|
||||
bool writeArm9BinPadding(char paddingByte, const std::string& savePath, bool isArm9FooterPresent);
|
||||
bool writeArm7BinPadding(char paddingByte, const std::string& savePath);
|
||||
bool writeFntPadding(char paddingByte, const std::string& savePath);
|
||||
bool writeFatPadding(char paddingByte, const std::string& savePath);
|
||||
bool writeRomPadding(const std::string& savePath);
|
||||
NFResult writeHeaderPadding(char paddingByte, const std::string& savePath);
|
||||
NFResult writeArm9BinPadding(char paddingByte, const std::string& savePath, bool isArm9FooterPresent);
|
||||
NFResult writeArm7BinPadding(char paddingByte, const std::string& savePath);
|
||||
NFResult writeFntPadding(char paddingByte, const std::string& savePath);
|
||||
NFResult writeFatPadding(char paddingByte, const std::string& savePath);
|
||||
NFResult writeRomPadding(const std::string& savePath);
|
||||
|
||||
QString extractPackerHeaderTableData(int index);
|
||||
|
||||
bool extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath);
|
||||
bool patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath);
|
||||
NFResult extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath, bool logFileIDs);
|
||||
NFResult patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath);
|
||||
NFResult buildFatData(const std::string& fatDataDirPath, const std::string& originalFatPath, uint32_t fatDataAddr, const std::string& savePath);
|
||||
};
|
||||
|
@ -697,6 +697,17 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fatExtractorSaveFileIDsCbx">
|
||||
<property name="text">
|
||||
<string>Save file IDs to _file_IDs.txt (required for rebuilding FAT)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_41">
|
||||
<property name="leftMargin">
|
||||
@ -725,6 +736,83 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_17">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_8">
|
||||
<property name="title">
|
||||
<string>FAT Builder</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_18">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_19">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Original fat.bin is required ONLY if the ROM has an overlay...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fatBuilderFatDirPathEdt"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fatBuilderOpenFatDataDirBtn">
|
||||
<property name="text">
|
||||
<string>Open FAT Data Directory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fatBuilderOriginalFatPathEdt"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fatBuilderLoadOriginalFatBtn">
|
||||
<property name="text">
|
||||
<string>Load Original fat.bin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Fat Files (fat_data.bin) Addr:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="fatBuilderFatAddrEdt"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QPushButton" name="fatBuilderBuildBtn">
|
||||
<property name="text">
|
||||
<string>Build!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
<item>
|
||||
|
@ -151,7 +151,7 @@ bool NDSHeaderModel::setData(const QModelIndex &index, const QVariant &value, in
|
||||
case 37: ndsHeader->DebugRomAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||
case 38: ndsHeader->DebugSize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||
case 39: ndsHeader->DebugRamAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||
case 40: QMessageBox::information(nullptr, tr("NDS Factory"), tr("FAT files address is automatically calculated based on Icon/Title address!")); break;
|
||||
case 40: QMessageBox::information(nullptr, tr("NDSFactory"), tr("FAT files address is automatically calculated based on Icon/Title address!")); break;
|
||||
default: return false;
|
||||
}
|
||||
Q_EMIT this->dataChanged(index, index);
|
||||
|
@ -1,13 +1,19 @@
|
||||
#include <filesystem>
|
||||
#include "./../../mainwindow.h"
|
||||
|
||||
|
||||
bool MainWindow::extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath)
|
||||
NFResult MainWindow::extractFatData(const std::string& fatDataSectionPath, const std::string& fatSectionPath,
|
||||
const std::string& fntSectionPath, uint32_t originalFatDataAddr, const std::string& savePath, bool logFileIDs)
|
||||
{
|
||||
return ndsFactory.extractFatData(fatDataSectionPath, fatSectionPath, fntSectionPath, originalFatDataAddr, savePath);
|
||||
return ndsFactory.extractFatData(fatDataSectionPath, fatSectionPath, fntSectionPath, originalFatDataAddr, savePath, logFileIDs);
|
||||
}
|
||||
|
||||
bool MainWindow::patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath)
|
||||
NFResult MainWindow::patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.patchFat(loadPath, shiftSize, savePath);
|
||||
}
|
||||
|
||||
NFResult MainWindow::buildFatData(const std::string& fatDataDirPath, const std::string& originalFatPath, uint32_t fatDataAddr, const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.buildFatData(fatDataDirPath, originalFatPath, fatDataAddr, savePath);
|
||||
}
|
||||
|
@ -2,13 +2,14 @@
|
||||
#include <QMessageBox>
|
||||
#include "./../../mainwindow.h"
|
||||
#include "./../../ui_mainwindow.h"
|
||||
#include "./../../utils/filepicker.h"
|
||||
|
||||
void MainWindow::on_fatExtractorLoadFatDataBtn_clicked()
|
||||
{
|
||||
QString FatDataPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fat Data",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS FAT_DATA (*.bin)");
|
||||
|
||||
if (!FatDataPath.isNull())
|
||||
@ -22,7 +23,7 @@ void MainWindow::on_fatExtractorLoadFatBtn_clicked()
|
||||
QString FatPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fat",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS FAT (*.bin)");
|
||||
|
||||
if (!FatPath.isNull())
|
||||
@ -36,7 +37,7 @@ void MainWindow::on_fatExtractorLoadFntBtn_clicked()
|
||||
QString FntPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fnt",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS FNT (*.bin)");
|
||||
|
||||
if (!FntPath.isNull())
|
||||
@ -47,18 +48,25 @@ void MainWindow::on_fatExtractorLoadFntBtn_clicked()
|
||||
|
||||
void MainWindow::on_fatExtractorExtractBtn_clicked()
|
||||
{
|
||||
ui->fatExtractorExtractBtn->setEnabled(false);
|
||||
|
||||
QString dirPath = QFileDialog::getExistingDirectory(
|
||||
this, tr("Select Directory"),
|
||||
"",
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
extractFatData(ui->fatExtractorFatDataPathEdt->text().toStdString(),
|
||||
ui->fatExtractorFatPathEdt->text().toStdString(),
|
||||
ui->fatExtractorFntPathEdt->text().toStdString(),
|
||||
ui->fatExtractorOriginalFatFilesAddrEdt->text().toUInt(nullptr, 16),
|
||||
dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("FAT files extraction completed!"))
|
||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error extracting FAT files!"));
|
||||
if (!dirPath.isNull()) {
|
||||
NFResult nfResult = extractFatData(ui->fatExtractorFatDataPathEdt->text().toStdString(),
|
||||
ui->fatExtractorFatPathEdt->text().toStdString(),
|
||||
ui->fatExtractorFntPathEdt->text().toStdString(),
|
||||
ui->fatExtractorOriginalFatFilesAddrEdt->text().toUInt(nullptr, 16),
|
||||
dirPath.toStdString(),
|
||||
ui->fatExtractorSaveFileIDsCbx->isChecked());
|
||||
nfResult.result? QMessageBox::information(this, tr("NDSFactory"), tr("FAT files extraction completed!"))
|
||||
: QMessageBox::critical(this, tr("NDSFactory"), nfResult.message.c_str());
|
||||
}
|
||||
|
||||
ui->fatExtractorExtractBtn->setEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
@ -67,41 +75,81 @@ void MainWindow::on_fatPatcherLoadFatBtn_clicked()
|
||||
QString fatPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fat",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS Fat (*.bin)");
|
||||
|
||||
if( !fatPath.isNull() )
|
||||
{
|
||||
ui->fatPatcherFatPathEdt->setText(fatPath.toUtf8());
|
||||
}
|
||||
if(!fatPath.isNull())
|
||||
ui->fatPatcherFatPathEdt->setText(fatPath.toUtf8());
|
||||
}
|
||||
|
||||
void MainWindow::on_fatPatcherPatchFatBtn_clicked()
|
||||
{
|
||||
ui->fatPatcherPatchFatBtn->setEnabled(false);
|
||||
|
||||
uint32_t positionDiff = 0;
|
||||
uint32_t originalPos = ui->fatPatcherOriginalFatFilesAddrEdt->text().toUInt(nullptr, 16);
|
||||
uint32_t newPos = ui->fatPatcherNewFatFilesAddrEdt->text().toUInt(nullptr, 16);
|
||||
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS FAT",
|
||||
"fat.bin",
|
||||
"Binary (*.bin)");
|
||||
QString dirPath = customSaveFileDialog("NDS FAT",
|
||||
"fat.bin",
|
||||
"Binary (*.bin)");
|
||||
|
||||
if(dirPath.isNull())
|
||||
if (!dirPath.isNull())
|
||||
{
|
||||
return;
|
||||
if(originalPos < newPos)
|
||||
positionDiff = newPos - originalPos;
|
||||
else
|
||||
positionDiff = originalPos - newPos;
|
||||
|
||||
NFResult nfResult = patchFat(ui->fatPatcherFatPathEdt->text().toStdString(), positionDiff, dirPath.toStdString());
|
||||
nfResult.result ? QMessageBox::information(this, tr("NDSFactory"), tr("FAT patching completed!"))
|
||||
: QMessageBox::critical(this, tr("NDSFactory"), nfResult.message.c_str());
|
||||
}
|
||||
|
||||
if (originalPos < newPos)
|
||||
{
|
||||
positionDiff = newPos-originalPos;
|
||||
} else {
|
||||
positionDiff = originalPos-newPos;
|
||||
}
|
||||
|
||||
patchFat(ui->fatPatcherFatPathEdt->text().toStdString(), positionDiff, dirPath.toStdString())
|
||||
? QMessageBox::information(this, tr("NDS Factory"), tr("FAT patching completed!"))
|
||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error patching FAT!"));
|
||||
|
||||
ui->fatPatcherPatchFatBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_fatBuilderOpenFatDataDirBtn_clicked()
|
||||
{
|
||||
QString fatDirPat = QFileDialog::getExistingDirectory(
|
||||
this, tr("Select Directory"),
|
||||
"",
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
if (!fatDirPat.isNull())
|
||||
ui->fatBuilderFatDirPathEdt->setText(fatDirPat.toUtf8());
|
||||
}
|
||||
|
||||
void MainWindow::on_fatBuilderLoadOriginalFatBtn_clicked()
|
||||
{
|
||||
QString fatPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fat",
|
||||
"",
|
||||
"NDS Fat (*.bin)");
|
||||
|
||||
if (!fatPath.isNull())
|
||||
ui->fatBuilderOriginalFatPathEdt->setText(fatPath.toUtf8());
|
||||
}
|
||||
|
||||
void MainWindow::on_fatBuilderBuildBtn_clicked()
|
||||
{
|
||||
ui->fatBuilderOpenFatDataDirBtn->setEnabled(false);
|
||||
|
||||
QString dirPath = QFileDialog::getExistingDirectory(
|
||||
this, tr("Select Directory"),
|
||||
"",
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
{
|
||||
NFResult nfResult = buildFatData(ui->fatBuilderFatDirPathEdt->text().toStdString(),
|
||||
ui->fatBuilderOriginalFatPathEdt->text().toStdString(),
|
||||
ui->fatBuilderFatAddrEdt->text().toUInt(nullptr, 16),
|
||||
dirPath.toStdString());
|
||||
nfResult.result? QMessageBox::information(this, tr("NDSFactory"), tr("fat_data.bin and fat.bin correctly built!"))
|
||||
: QMessageBox::critical(this, tr("NDSFactory"), nfResult.message.c_str());
|
||||
}
|
||||
|
||||
ui->fatBuilderOpenFatDataDirBtn->setEnabled(true);
|
||||
}
|
@ -102,17 +102,17 @@ void MainWindow::calcHeaderCrc16()
|
||||
ui->packerHeaderDataTable->model()->setData(headerCrcIndex, QString::number(ndsFactory.calcHeaderCrc16(romHeaderBuffer), 16), Qt::EditRole);
|
||||
}
|
||||
|
||||
bool MainWindow::writeHeader(const std::string& savePath)
|
||||
NFResult MainWindow::writeHeader(const std::string& savePath)
|
||||
{
|
||||
std::vector<char> romHeaderBuffer(sizeof(NDSHeader));
|
||||
NDSHeader* pRomHeader = reinterpret_cast<NDSHeader*>(romHeaderBuffer.data());
|
||||
|
||||
generateHeader(pRomHeader);
|
||||
|
||||
return ndsFactory.writeBytesToFile(romHeaderBuffer, savePath, 0, sizeof(NDSHeader));;
|
||||
return ndsFactory.writeBytesToFile(romHeaderBuffer, savePath, 0, sizeof(NDSHeader));
|
||||
}
|
||||
|
||||
bool MainWindow::writeHeaderPadding(char paddingType, const std::string& savePath)
|
||||
NFResult MainWindow::writeHeaderPadding(char paddingType, const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = sizeof(NDSHeader);
|
||||
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::ARM9RomAddress).toUInt(nullptr, 16) - startAddr;
|
||||
@ -124,7 +124,7 @@ bool MainWindow::writeHeaderPadding(char paddingType, const std::string& savePat
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent)
|
||||
NFResult MainWindow::writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent)
|
||||
{
|
||||
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16);
|
||||
if (isArm9FooterPresent)
|
||||
@ -137,7 +137,7 @@ bool MainWindow::writeArm9Bin(const std::string& savePath, bool isArm9FooterPres
|
||||
}
|
||||
|
||||
|
||||
bool MainWindow::writeArm9BinPadding(char paddingType, const std::string& savePath, bool isFooterPresent)
|
||||
NFResult MainWindow::writeArm9BinPadding(char paddingType, const std::string& savePath, bool isFooterPresent)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9RomAddress).toUInt(nullptr, 16) +
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16);
|
||||
@ -148,7 +148,10 @@ bool MainWindow::writeArm9BinPadding(char paddingType, const std::string& savePa
|
||||
size = extractPackerHeaderTableData(NDSHeaderNames::ARM7RomAddress).toUInt(nullptr, 16) - startAddr;
|
||||
|
||||
if (isFooterPresent)
|
||||
{
|
||||
startAddr += Arm9FooterSize;
|
||||
size -= Arm9FooterSize;
|
||||
}
|
||||
|
||||
return ndsFactory.writePaddingToFile(
|
||||
paddingType,
|
||||
@ -157,7 +160,7 @@ bool MainWindow::writeArm9BinPadding(char paddingType, const std::string& savePa
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm9Overlay(const std::string& savePath)
|
||||
NFResult MainWindow::writeArm9Overlay(const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.writeSectionToFile(
|
||||
ui->loadedArm9OverlayPathEdt->text().toStdString(),
|
||||
@ -166,7 +169,7 @@ bool MainWindow::writeArm9Overlay(const std::string& savePath)
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlaySize).toUInt(nullptr, 16));
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm9OverlayFiles(const std::string& savePath)
|
||||
NFResult MainWindow::writeArm9OverlayFiles(const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16) +
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlaySize).toUInt(nullptr, 16);
|
||||
@ -178,7 +181,7 @@ bool MainWindow::writeArm9OverlayFiles(const std::string& savePath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm7Bin(const std::string& savePath)
|
||||
NFResult MainWindow::writeArm7Bin(const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.writeSectionToFile(
|
||||
ui->loadedArm7BinPathEdt->text().toStdString(),
|
||||
@ -187,7 +190,7 @@ bool MainWindow::writeArm7Bin(const std::string& savePath)
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM7Size).toUInt(nullptr, 16));
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm7BinPadding(char paddingType, const std::string& savePath)
|
||||
NFResult MainWindow::writeArm7BinPadding(char paddingType, const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7RomAddress).toUInt(nullptr, 16) +
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM7Size).toUInt(nullptr, 16);
|
||||
@ -204,7 +207,7 @@ bool MainWindow::writeArm7BinPadding(char paddingType, const std::string& savePa
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm7Overlay(const std::string& savePath)
|
||||
NFResult MainWindow::writeArm7Overlay(const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.writeSectionToFile(
|
||||
ui->loadedArm7OverlayPathEdt->text().toStdString(),
|
||||
@ -213,7 +216,7 @@ bool MainWindow::writeArm7Overlay(const std::string& savePath)
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM7OverlaySize).toUInt(nullptr, 16));
|
||||
}
|
||||
|
||||
bool MainWindow::writeArm7OverlayFiles(const std::string& savePath)
|
||||
NFResult MainWindow::writeArm7OverlayFiles(const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7OverlayAddress).toUInt(nullptr, 16) +
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM7OverlaySize).toUInt(nullptr, 16);
|
||||
@ -225,7 +228,7 @@ bool MainWindow::writeArm7OverlayFiles(const std::string& savePath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeFnt(const std::string& savePath)
|
||||
NFResult MainWindow::writeFnt(const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.writeSectionToFile(
|
||||
ui->loadedFntPathEdt->text().toStdString(),
|
||||
@ -234,7 +237,7 @@ bool MainWindow::writeFnt(const std::string& savePath)
|
||||
extractPackerHeaderTableData(NDSHeaderNames::FilenameTableSize).toUInt(nullptr, 16));
|
||||
}
|
||||
|
||||
bool MainWindow::writeFntPadding(char paddingType, const std::string& savePath)
|
||||
NFResult MainWindow::writeFntPadding(char paddingType, const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::FilenameTableAddress).toUInt(nullptr, 16) +
|
||||
extractPackerHeaderTableData(NDSHeaderNames::FilenameTableSize).toUInt(nullptr, 16);
|
||||
@ -247,7 +250,7 @@ bool MainWindow::writeFntPadding(char paddingType, const std::string& savePath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeFat(const std::string& savePath)
|
||||
NFResult MainWindow::writeFat(const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.writeSectionToFile(
|
||||
ui->loadedFatPathEdt->text().toStdString(),
|
||||
@ -256,7 +259,7 @@ bool MainWindow::writeFat(const std::string& savePath)
|
||||
extractPackerHeaderTableData(NDSHeaderNames::FATSize).toUInt(nullptr, 16));
|
||||
}
|
||||
|
||||
bool MainWindow::writeFatPadding(char paddingType, const std::string& savePath)
|
||||
NFResult MainWindow::writeFatPadding(char paddingType, const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::FATAddress).toUInt(nullptr, 16) +
|
||||
extractPackerHeaderTableData(NDSHeaderNames::FATSize).toUInt(nullptr, 16);
|
||||
@ -269,7 +272,7 @@ bool MainWindow::writeFatPadding(char paddingType, const std::string& savePath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeIconTitle(const std::string& savePath)
|
||||
NFResult MainWindow::writeIconTitle(const std::string& savePath)
|
||||
{
|
||||
return ndsFactory.writeSectionToFile(
|
||||
ui->loadedIconTitlePathEdt->text().toStdString(),
|
||||
@ -278,7 +281,7 @@ bool MainWindow::writeIconTitle(const std::string& savePath)
|
||||
IconTitleSize);
|
||||
}
|
||||
|
||||
bool MainWindow::writeFatFiles(const std::string& savePath)
|
||||
NFResult MainWindow::writeFatFiles(const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::IconTitleAddress).toUInt(nullptr, 16) + IconTitleSize;
|
||||
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::UsedRomSize).toUInt(nullptr, 16) - startAddr;
|
||||
@ -290,7 +293,7 @@ bool MainWindow::writeFatFiles(const std::string& savePath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeRomPadding(const std::string& savePath)
|
||||
NFResult MainWindow::writeRomPadding(const std::string& savePath)
|
||||
{
|
||||
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::UsedRomSize).toUInt(nullptr, 16);
|
||||
uint32_t size = static_cast<uint32_t>(ndsFactory.getCardSizeInBytes(extractPackerHeaderTableData(NDSHeaderNames::CardSize).toInt())) - startAddr;
|
||||
@ -302,9 +305,9 @@ bool MainWindow::writeRomPadding(const std::string& savePath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::writeEverything(const std::string& savePath)
|
||||
NFResult MainWindow::writeEverything(const std::string& savePath)
|
||||
{
|
||||
bool res = true;
|
||||
NFResult nfResult;
|
||||
char paddingType;
|
||||
bool isArm9FooterPresent = ndsFactory.checkArm9FooterPresence(ui->loadedArm9BinPathEdt->text().toStdString(),
|
||||
extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16));
|
||||
@ -315,32 +318,49 @@ bool MainWindow::writeEverything(const std::string& savePath)
|
||||
|
||||
std::remove(savePath.c_str());
|
||||
|
||||
res &= writeHeader(savePath);
|
||||
res &= writeHeaderPadding(paddingType, savePath);
|
||||
res &= writeArm9Bin(savePath, isArm9FooterPresent);
|
||||
res &= writeArm9BinPadding(paddingType, savePath, isArm9FooterPresent);
|
||||
nfResult = writeHeader(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeHeaderPadding(paddingType, savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeArm9Bin(savePath, isArm9FooterPresent);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeArm9BinPadding(paddingType, savePath, isArm9FooterPresent);
|
||||
if (!nfResult.result) return nfResult;
|
||||
if (extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16) != 0)
|
||||
{
|
||||
res &= writeArm9Overlay(savePath);
|
||||
res &= writeArm9OverlayFiles(savePath);
|
||||
nfResult = writeArm9Overlay(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeArm9OverlayFiles(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
}
|
||||
res &= writeArm7Bin(savePath);
|
||||
res &= writeArm7BinPadding(paddingType, savePath);
|
||||
nfResult = writeArm7Bin(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeArm7BinPadding(paddingType, savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
if (extractPackerHeaderTableData(NDSHeaderNames::ARM7OverlayAddress).toUInt(nullptr, 16) != 0) {
|
||||
res &= writeArm7Overlay(savePath);
|
||||
res &= writeArm7OverlayFiles(savePath);
|
||||
nfResult = writeArm7Overlay(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeArm7OverlayFiles(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
}
|
||||
res &= writeFnt(savePath);
|
||||
res &= writeFntPadding(paddingType, savePath);
|
||||
res &= writeFat(savePath);
|
||||
res &= writeFatPadding(paddingType, savePath);
|
||||
res &= writeIconTitle(savePath);
|
||||
res &= writeFatFiles(savePath);
|
||||
nfResult = writeFnt(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeFntPadding(paddingType, savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeFat(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeFatPadding(paddingType, savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeIconTitle(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = writeFatFiles(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
if(!ui->packerTrimRomsCbx->isChecked())
|
||||
{
|
||||
res &= writeRomPadding(savePath);
|
||||
nfResult = writeRomPadding(savePath);
|
||||
if (!nfResult.result) return nfResult;
|
||||
}
|
||||
return res;
|
||||
return { true, "" };
|
||||
}
|
||||
|
||||
QString MainWindow::extractPackerHeaderTableData(int index)
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <QMessageBox>
|
||||
#include "./../../mainwindow.h"
|
||||
#include "./../../ui_mainwindow.h"
|
||||
#include "./../../utils/filepicker.h"
|
||||
#include "../commons/headernames.h"
|
||||
|
||||
|
||||
@ -15,13 +16,9 @@ void MainWindow::on_packerLoadHeaderBtn_clicked()
|
||||
QDir::currentPath(),
|
||||
"NDS Header (*.bin)");
|
||||
|
||||
if(headerPath.isNull())
|
||||
{
|
||||
QMessageBox::critical(this, tr("NDS Factory"), tr("Unable to open file!"));
|
||||
return;
|
||||
}
|
||||
if (headerPath.isNull()) return;
|
||||
|
||||
if (ndsFactory.loadRomHeader(headerPath.toStdString(), romHeader))
|
||||
if (ndsFactory.loadRomHeader(headerPath.toStdString(), romHeader).result)
|
||||
{
|
||||
pNDSHeader = reinterpret_cast<NDSHeader*>(romHeader.data());
|
||||
populatePackerSectionHeader(pNDSHeader);
|
||||
@ -35,7 +32,7 @@ void MainWindow::on_packerLoadArm9BinBtn_clicked()
|
||||
QString arm9BinPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Arm9Bin",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS Arm9Bin (*.bin)");
|
||||
|
||||
if(!arm9BinPath.isNull())
|
||||
@ -49,7 +46,7 @@ void MainWindow::on_packerLoadArm7BinBtn_clicked()
|
||||
QString arm7BinPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Arm7Bin",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS Arm7Bin (*.bin)");
|
||||
|
||||
if(!arm7BinPath.isNull())
|
||||
@ -63,7 +60,7 @@ void MainWindow::on_packerLoadFntBtn_clicked()
|
||||
QString fntPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fnt",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS Fnt (*.bin)");
|
||||
|
||||
if(!fntPath.isNull())
|
||||
@ -77,7 +74,7 @@ void MainWindow::on_packerLoadFatBtn_clicked()
|
||||
QString fatPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fat",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS Fat (*.bin)");
|
||||
|
||||
if(!fatPath.isNull())
|
||||
@ -91,7 +88,7 @@ void MainWindow::on_packerLoadArm9OverlayBtn_clicked()
|
||||
QString arm9OverlayPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Arm9Overlay",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS A9OVR (*.bin)");
|
||||
|
||||
if( !arm9OverlayPath.isNull() )
|
||||
@ -105,7 +102,7 @@ void MainWindow::on_packerLoadArm9OverlayFilesBtn_clicked()
|
||||
QString arm9OverlayFilesPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Arm9Overlay Data",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS A9OVR_DATA (*.bin)");
|
||||
|
||||
if(!arm9OverlayFilesPath.isNull())
|
||||
@ -119,7 +116,7 @@ void MainWindow::on_packerLoadArm7OverlayBtn_clicked()
|
||||
QString arm7OverlayPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Arm7Overlay",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS A7OVR (*.bin)");
|
||||
|
||||
if(!arm7OverlayPath.isNull())
|
||||
@ -133,7 +130,7 @@ void MainWindow::on_packerLoadArm7OverlayFilesBtn_clicked()
|
||||
QString arm7OverlayFilesPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Arm7Overlay Data",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS A7OVR_DATA (*.bin)");
|
||||
|
||||
if(!arm7OverlayFilesPath.isNull())
|
||||
@ -147,7 +144,7 @@ void MainWindow::on_packerLoadIconTitleBtn_clicked()
|
||||
QString iconTitlePath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS IconTitleLogo",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS ITL (*.bin)");
|
||||
|
||||
if(!iconTitlePath.isNull())
|
||||
@ -161,7 +158,7 @@ void MainWindow::on_packerLoadFatFilesBtn_clicked()
|
||||
QString fatFilesPath = QFileDialog::getOpenFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Fat Data",
|
||||
QDir::currentPath(),
|
||||
"",
|
||||
"NDS FAT_DATA (*.bin)");
|
||||
|
||||
if(!fatFilesPath.isNull())
|
||||
@ -172,17 +169,19 @@ void MainWindow::on_packerLoadFatFilesBtn_clicked()
|
||||
|
||||
void MainWindow::on_packerBuildNDSRomBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Rom",
|
||||
"rom.nds",
|
||||
"NDS ROM (*.nds)");
|
||||
ui->packerBuildNDSRomBtn->setEnabled(false);
|
||||
|
||||
QString dirPath = customSaveFileDialog("NDS Rom",
|
||||
"rom.nds",
|
||||
"NDS ROM (*.nds)");
|
||||
|
||||
if (!dirPath.isNull())
|
||||
{
|
||||
writeEverything(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Creation completed!"))
|
||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the creation!"));
|
||||
NFResult nfResult = writeEverything(dirPath.toStdString());
|
||||
nfResult.result? QMessageBox::information(this, tr("NDSFactory"), tr("Creation completed!"))
|
||||
: QMessageBox::critical(this, tr("NDSFactory"), nfResult.message.c_str());
|
||||
}
|
||||
ui->packerBuildNDSRomBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_packerCalcHeaderCrcBtn_clicked()
|
||||
|
@ -23,14 +23,26 @@ void MainWindow::enableExtractionButtons()
|
||||
{
|
||||
ui->unpackerExtractorGbx->setEnabled(true);
|
||||
ui->unpackerExtraGbx->setEnabled(true);
|
||||
if (ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlayAddress, 1).data().toString().toUInt(nullptr,16) == 0){
|
||||
if (ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlayAddress, 1).data().toString().toUInt(nullptr,16) == 0)
|
||||
{
|
||||
ui->unpackerDumpArm9OverlayBtn->setEnabled(false);
|
||||
ui->unpackerDumpArm9OverlayFilesBtn->setEnabled(false);
|
||||
}
|
||||
if (ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlayAddress, 1).data().toString().toUInt(nullptr,16) == 0){
|
||||
else
|
||||
{
|
||||
ui->unpackerDumpArm9OverlayBtn->setEnabled(true);
|
||||
ui->unpackerDumpArm9OverlayFilesBtn->setEnabled(true);
|
||||
}
|
||||
if (ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlayAddress, 1).data().toString().toUInt(nullptr,16) == 0)
|
||||
{
|
||||
ui->unpackerDumpArm7OverlayBtn->setEnabled(false);
|
||||
ui->unpackerDumpArm7OverlayFilesBtn->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->unpackerDumpArm7OverlayBtn->setEnabled(true);
|
||||
ui->unpackerDumpArm7OverlayFilesBtn->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::disableExtractionButtons()
|
||||
@ -39,7 +51,7 @@ void MainWindow::disableExtractionButtons()
|
||||
ui->unpackerExtraGbx->setEnabled(false);
|
||||
}
|
||||
|
||||
bool MainWindow::dumpHeader(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpHeader(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -48,7 +60,7 @@ bool MainWindow::dumpHeader(const std::string& dirPath)
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::HeaderSize, 1).data().toString().toUInt(nullptr,16));
|
||||
}
|
||||
|
||||
bool MainWindow::dumpArm9Bin(const std::string& dirPath, bool dumpExtraBytes)
|
||||
NFResult MainWindow::dumpArm9Bin(const std::string& dirPath, bool dumpExtraBytes)
|
||||
{
|
||||
uint32_t size = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9Size, 1).data().toString().toUInt(nullptr,16);
|
||||
if (dumpExtraBytes)
|
||||
@ -60,7 +72,7 @@ bool MainWindow::dumpArm9Bin(const std::string& dirPath, bool dumpExtraBytes)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::dumpArm7Bin(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpArm7Bin(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -69,7 +81,7 @@ bool MainWindow::dumpArm7Bin(const std::string& dirPath)
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7Size, 1).data().toString().toUInt(nullptr,16));
|
||||
}
|
||||
|
||||
bool MainWindow::dumpFnt(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpFnt(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -78,7 +90,7 @@ bool MainWindow::dumpFnt(const std::string& dirPath)
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FilenameTableSize, 1).data().toString().toUInt(nullptr,16));
|
||||
}
|
||||
|
||||
bool MainWindow::dumpFat(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpFat(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -87,7 +99,7 @@ bool MainWindow::dumpFat(const std::string& dirPath)
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FATSize, 1).data().toString().toUInt(nullptr,16));
|
||||
}
|
||||
|
||||
bool MainWindow::dumpArm9Overlay(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpArm9Overlay(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -96,7 +108,7 @@ bool MainWindow::dumpArm9Overlay(const std::string& dirPath)
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlaySize, 1).data().toString().toUInt(nullptr,16));
|
||||
}
|
||||
|
||||
bool MainWindow::dumpArm9OverlayFiles(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpArm9OverlayFiles(const std::string& dirPath)
|
||||
{
|
||||
uint32_t startAddr = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlayAddress, 1).data().toString().toUInt(nullptr, 16) +
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlaySize, 1).data().toString().toUInt(nullptr, 16);
|
||||
@ -109,7 +121,7 @@ bool MainWindow::dumpArm9OverlayFiles(const std::string& dirPath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::dumpArm7Overlay(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpArm7Overlay(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -118,7 +130,7 @@ bool MainWindow::dumpArm7Overlay(const std::string& dirPath)
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlaySize, 1).data().toString().toUInt(nullptr,16));
|
||||
}
|
||||
|
||||
bool MainWindow::dumpArm7OverlayFiles(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpArm7OverlayFiles(const std::string& dirPath)
|
||||
{
|
||||
uint32_t startAddr = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlayAddress, 1).data().toString().toUInt(nullptr, 16) +
|
||||
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlaySize, 1).data().toString().toUInt(nullptr, 16);
|
||||
@ -131,7 +143,7 @@ bool MainWindow::dumpArm7OverlayFiles(const std::string& dirPath)
|
||||
size);
|
||||
}
|
||||
|
||||
bool MainWindow::dumpIconTitle(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpIconTitle(const std::string& dirPath)
|
||||
{
|
||||
return ndsFactory.dumpDataFromFile(
|
||||
ui->loadedRomPath->text().toStdString(),
|
||||
@ -140,7 +152,7 @@ bool MainWindow::dumpIconTitle(const std::string& dirPath)
|
||||
ICON_TITLE_SIZE);
|
||||
}
|
||||
|
||||
bool MainWindow::dumpFatFiles(const std::string& dirPath)
|
||||
NFResult MainWindow::dumpFatFiles(const std::string& dirPath)
|
||||
{
|
||||
uint32_t startAddr = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::IconTitleAddress, 1).data().toString().toUInt(nullptr,16) + IconTitleSize ;
|
||||
uint32_t size = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::UsedRomSize, 1).data().toString().toUInt(nullptr,16) - startAddr;
|
||||
@ -153,23 +165,34 @@ bool MainWindow::dumpFatFiles(const std::string& dirPath)
|
||||
}
|
||||
|
||||
|
||||
bool MainWindow::dumpEverything(QString dirPath)
|
||||
NFResult MainWindow::dumpEverything(QString dirPath)
|
||||
{
|
||||
bool result = true;
|
||||
result &= dumpHeader(QDir::toNativeSeparators(dirPath+"/header.bin").toStdString());
|
||||
result &= dumpArm9Bin(QDir::toNativeSeparators(dirPath+"/arm9.bin").toStdString(), true);
|
||||
result &= dumpArm7Bin(QDir::toNativeSeparators(dirPath+"/arm7.bin").toStdString());
|
||||
result &= dumpFnt(QDir::toNativeSeparators(dirPath+"/fnt.bin").toStdString());
|
||||
result &= dumpFat(QDir::toNativeSeparators(dirPath+"/fat.bin").toStdString());
|
||||
NFResult nfResult;
|
||||
nfResult = dumpHeader(QDir::toNativeSeparators(dirPath + "/header.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpArm9Bin(QDir::toNativeSeparators(dirPath+"/arm9.bin").toStdString(), true);
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpArm7Bin(QDir::toNativeSeparators(dirPath+"/arm7.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpFnt(QDir::toNativeSeparators(dirPath+"/fnt.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpFat(QDir::toNativeSeparators(dirPath+"/fat.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
if(ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlayAddress, 1).data().toString().toUInt(nullptr,16) != 0) {
|
||||
result &= dumpArm9Overlay(QDir::toNativeSeparators(dirPath+"/a9ovr.bin").toStdString());
|
||||
result &= dumpArm9OverlayFiles(QDir::toNativeSeparators(dirPath+"/a9ovr_data.bin").toStdString());
|
||||
nfResult = dumpArm9Overlay(QDir::toNativeSeparators(dirPath+"/a9ovr.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpArm9OverlayFiles(QDir::toNativeSeparators(dirPath+"/a9ovr_data.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
}
|
||||
if(ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlayAddress, 1).data().toString().toUInt(nullptr,16) != 0) {
|
||||
result &= dumpArm7Overlay(QDir::toNativeSeparators(dirPath+"/a7ovr.bin").toStdString());
|
||||
result &= dumpArm7OverlayFiles(QDir::toNativeSeparators(dirPath+"/a7ovr_data.bin").toStdString());
|
||||
}
|
||||
result &= dumpIconTitle(QDir::toNativeSeparators(dirPath+"/itl.bin").toStdString());
|
||||
result &= dumpFatFiles(QDir::toNativeSeparators(dirPath+"/fat_data.bin").toStdString());
|
||||
return result;
|
||||
nfResult = dumpArm7Overlay(QDir::toNativeSeparators(dirPath+"/a7ovr.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpArm7OverlayFiles(QDir::toNativeSeparators(dirPath+"/a7ovr_data.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
}
|
||||
nfResult = dumpIconTitle(QDir::toNativeSeparators(dirPath+"/itl.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
nfResult = dumpFatFiles(QDir::toNativeSeparators(dirPath+"/fat_data.bin").toStdString());
|
||||
if (!nfResult.result) return nfResult;
|
||||
return { true, "" };
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <QMessageBox>
|
||||
#include "./../../mainwindow.h"
|
||||
#include "./../../ui_mainwindow.h"
|
||||
#include "./../../utils/filepicker.h"
|
||||
#include "./../../utils/ui.h"
|
||||
|
||||
|
||||
void MainWindow::on_loadRomBtn_clicked()
|
||||
@ -15,12 +17,11 @@ void MainWindow::on_loadRomBtn_clicked()
|
||||
QDir::currentPath(),
|
||||
"NDS Rom (*.nds)");
|
||||
|
||||
if( !romPath.isNull() )
|
||||
{
|
||||
ui->loadedRomPath->setText(romPath.toUtf8());
|
||||
}
|
||||
if (romPath.isNull()) return;
|
||||
|
||||
if (ndsFactory.loadRomHeader(ui->loadedRomPath->text().toStdString(), romHeader))
|
||||
ui->loadedRomPath->setText(romPath.toUtf8());
|
||||
|
||||
if (ndsFactory.loadRomHeader(ui->loadedRomPath->text().toStdString(), romHeader).result)
|
||||
{
|
||||
pNDSHeader = reinterpret_cast<NDSHeader*>(romHeader.data());
|
||||
populateHeader(pNDSHeader);
|
||||
@ -34,132 +35,135 @@ void MainWindow::on_loadRomBtn_clicked()
|
||||
|
||||
void MainWindow::on_unpackerDumpHeaderBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS Header",
|
||||
"header.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpHeaderBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpHeader(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS Header", "header.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpHeader(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpHeaderBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpArm9Btn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS ARM9",
|
||||
"arm9.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpArm9Btn->setEnabled(false);
|
||||
|
||||
QString dirPath = customSaveFileDialog("NDS ARM9", "arm9.bin", "Binary (*.bin)");
|
||||
|
||||
QMessageBox::StandardButton dumpExtraBytes = QMessageBox::question(
|
||||
this,
|
||||
"NDS Factory",
|
||||
"NDSFactory",
|
||||
"Do you want to dump the extra 12 bytes? (click yes if you want a 1:1 arm9 dump)",
|
||||
QMessageBox::Yes|QMessageBox::No);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpArm9Bin(dirPath.toStdString(), dumpExtraBytes == QMessageBox::Yes ? true : false));
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpArm9Bin(dirPath.toStdString(), dumpExtraBytes == QMessageBox::Yes ? true : false));
|
||||
|
||||
ui->unpackerDumpArm9Btn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpArm7Btn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS ARM7",
|
||||
"arm7.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpArm7Btn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpArm7Bin(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS ARM7", "arm7.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpArm7Bin(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpArm7Btn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpFntBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS FNT",
|
||||
"fnt.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpFntBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpFnt(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS FNT", "fnt.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpFnt(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpFntBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpFatBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS FAT",
|
||||
"fat.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpFatBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpFat(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS FAT", "fat.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpFat(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpFatBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpArm9OverlayBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS ARM9 Overlay",
|
||||
"a9ovr.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpArm9OverlayBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpArm9Overlay(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS ARM9 Overlay", "a9ovr.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpArm9Overlay(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpArm9OverlayBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpArm7OverlayBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS ARM7 Overlay",
|
||||
"a7ovr.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpArm7OverlayBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpArm7Overlay(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS ARM7 Overlay", "a7ovr.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpArm7Overlay(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpArm7OverlayBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpIconTitleLogoBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS IconTitleLogo",
|
||||
"itl.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpIconTitleLogoBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpIconTitle(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS IconTitleLogo", "itl.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpIconTitle(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpIconTitleLogoBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpFatFilesBtn_clicked()
|
||||
{
|
||||
QString dirPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
"NDS FAT Files",
|
||||
"fat_data.bin",
|
||||
"Binary (*.bin)");
|
||||
ui->unpackerDumpFatFilesBtn->setEnabled(false);
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpFatFiles(dirPath.toStdString()));
|
||||
QString dirPath = customSaveFileDialog("NDS FAT Files", "fat_data.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpFatFiles(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpFatFilesBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpArm9OverlayFilesBtn_clicked()
|
||||
{
|
||||
QMessageBox::warning(this, tr("NDS Factory"), tr("This function is currently not implemented!"));
|
||||
//dumpArm9OverlayFiles()
|
||||
ui->unpackerDumpArm9OverlayFilesBtn->setEnabled(false);
|
||||
|
||||
QString dirPath = customSaveFileDialog("NDS ARM9 Overlay Data", "a9ovr_data.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull()) notifyExtractionResult(dumpArm9OverlayFiles(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpArm9OverlayFilesBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpArm7OverlayFilesBtn_clicked()
|
||||
{
|
||||
QMessageBox::warning(this, tr("NDS Factory"), tr("This function is currently not implemented!"));
|
||||
//dumpArm7OverlayFiles()
|
||||
ui->unpackerDumpArm7OverlayFilesBtn->setEnabled(false);
|
||||
|
||||
QString dirPath = customSaveFileDialog("NDS ARM7 Overlay Data", "a7ovr_data.bin", "Binary (*.bin)");
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpArm7OverlayFiles(dirPath.toStdString()));
|
||||
|
||||
ui->unpackerDumpArm7OverlayFilesBtn->setEnabled(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_unpackerDumpEverythingBtn_clicked()
|
||||
{
|
||||
ui->unpackerDumpEverythingBtn->setEnabled(false);
|
||||
QString dirPath = QFileDialog::getExistingDirectory(
|
||||
this, tr("Select Directory"),
|
||||
"",
|
||||
@ -167,16 +171,5 @@ void MainWindow::on_unpackerDumpEverythingBtn_clicked()
|
||||
|
||||
if (!dirPath.isNull())
|
||||
notifyExtractionResult(dumpEverything(dirPath));
|
||||
}
|
||||
|
||||
void MainWindow::notifyExtractionResult(bool result)
|
||||
{
|
||||
if(result)
|
||||
{
|
||||
QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
||||
}
|
||||
ui->unpackerDumpEverythingBtn->setEnabled(true);
|
||||
}
|
20
ui/utils/filepicker.h
Normal file
20
ui/utils/filepicker.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
inline QString customSaveFileDialog(const QString& title, const QString& defaultName, const QString& filter)
|
||||
{
|
||||
|
||||
static QString lastUsedPath;
|
||||
|
||||
QString selectedPath = QFileDialog::getSaveFileName(
|
||||
Q_NULLPTR,
|
||||
title,
|
||||
lastUsedPath + defaultName,
|
||||
filter);
|
||||
|
||||
if (!selectedPath.isNull())
|
||||
lastUsedPath = selectedPath.mid(0, selectedPath.lastIndexOf('/', Qt::CaseInsensitive)+1);
|
||||
|
||||
return selectedPath;
|
||||
}
|
@ -49,7 +49,7 @@ inline void setTheme(QString themeValue)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("theme", themeValue);
|
||||
QMessageBox::information(nullptr, "NDS Factory", "Restart NDSFactory to change theme!");
|
||||
QMessageBox::information(nullptr, "NDSFactory", "Restart NDSFactory to change theme!");
|
||||
|
||||
}
|
||||
|
||||
|
16
ui/utils/ui.h
Normal file
16
ui/utils/ui.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <QMessageBox>
|
||||
#include "../../ndsfactory/nfresult.h"
|
||||
|
||||
void notifyExtractionResult(NFResult nfResult)
|
||||
{
|
||||
if (nfResult.result)
|
||||
{
|
||||
QMessageBox::information(Q_NULLPTR, "NDSFactory", "Extraction completed!");
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::critical(Q_NULLPTR, "NDSFactory", nfResult.message.c_str());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user