mirror of
https://github.com/Luca1991/NDSFactory.git
synced 2026-02-07 15:16:15 +01:00
Compare commits
23 Commits
V1.0
...
d69e4e13fa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d69e4e13fa | ||
|
|
4b886a9033 | ||
|
|
aa2ed50ade | ||
|
|
ec81e2bfbe | ||
|
|
30425b6bb8 | ||
|
|
319d0e232e | ||
|
|
f64b0702a4 | ||
|
|
31148e2337 | ||
|
|
7f81130d90 | ||
|
|
93a037e6c1 | ||
|
|
658ca1b74c | ||
|
|
c8fc9006f2 | ||
|
|
b334ff78ff | ||
|
|
3c7bae69f8 | ||
|
|
bf8224eeb0 | ||
|
|
439fe70f31 | ||
|
|
573fc3b3cd | ||
|
|
1b7e29a7b0 | ||
|
|
a4c6b5f66e | ||
|
|
a3e006fa2f | ||
|
|
d0d4138d3f | ||
|
|
aaa60c9bb0 | ||
|
|
33d797ca21 |
130
.github/workflows/build.yml
vendored
Normal file
130
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
name: Build and Release on Tag
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-linux:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- 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: 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: 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"
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4.1.7
|
||||||
|
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v4
|
||||||
|
with:
|
||||||
|
version: '6.7.2'
|
||||||
|
|
||||||
|
- name: Install CMake
|
||||||
|
uses: lukka/get-cmake@latest
|
||||||
|
|
||||||
|
- name: Create Build Environment
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
|
||||||
|
- 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
|
||||||
|
macdeployqt NDSFactory.app
|
||||||
|
|
||||||
|
- 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: 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"
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4.1.7
|
||||||
|
|
||||||
|
- name: Install Qt
|
||||||
|
uses: jurplel/install-qt-action@v4
|
||||||
|
with:
|
||||||
|
version: '6.7.2'
|
||||||
|
|
||||||
|
- name: Install CMake
|
||||||
|
uses: lukka/get-cmake@latest
|
||||||
|
|
||||||
|
- name: Create Build Environment
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
|
||||||
|
- 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: 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"
|
||||||
398
.gitignore
vendored
398
.gitignore
vendored
@@ -41,3 +41,401 @@ target_wrapper.*
|
|||||||
|
|
||||||
# QtCreator CMake
|
# QtCreator CMake
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
|
|
||||||
|
# OS specific
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
out/
|
||||||
|
build/
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
||||||
|
|||||||
105
CMakeLists.txt
Normal file
105
CMakeLists.txt
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.25)
|
||||||
|
|
||||||
|
project(NDSFactory)
|
||||||
|
|
||||||
|
# Require Qt6 components
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||||
|
|
||||||
|
# Include sanitizers
|
||||||
|
include(${CMAKE_SOURCE_DIR}/cmake/sanitizers.cmake)
|
||||||
|
|
||||||
|
# Determine the Git commit hash if in a git repository
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||||
|
execute_process(
|
||||||
|
COMMAND git log -1 --format=%h
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(GIT_COMMIT_HASH "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Configure the revision header file
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/ui/dialogs/about/revision.h.in
|
||||||
|
${CMAKE_SOURCE_DIR}/ui/dialogs/about/revision.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Collect source and header files
|
||||||
|
## Dialogs
|
||||||
|
file(GLOB_RECURSE DIALOGS_HEADERS ui/dialogs/*.h)
|
||||||
|
file(GLOB_RECURSE DIALOGS_SOURCES ui/dialogs/*.cpp)
|
||||||
|
file(GLOB_RECURSE DIALOGS_UIS ui/dialogs/*.ui)
|
||||||
|
|
||||||
|
## Tabs
|
||||||
|
file(GLOB_RECURSE TABS_HEADERS ui/tabs/*.h)
|
||||||
|
file(GLOB_RECURSE TABS_SOURCES ui/tabs/*.cpp)
|
||||||
|
|
||||||
|
## Models
|
||||||
|
file(GLOB_RECURSE MODELS_HEADERS ui/models/*.h)
|
||||||
|
file(GLOB_RECURSE MODELS_SOURCES ui/models/*.cpp)
|
||||||
|
|
||||||
|
## Utils
|
||||||
|
file(GLOB_RECURSE UTILS_HEADERS ui/utils/*.h)
|
||||||
|
|
||||||
|
## NDSFactory
|
||||||
|
file(GLOB_RECURSE NDSFACTORY_SOURCES ndsfactory/*.cpp)
|
||||||
|
file(GLOB_RECURSE NDSFACTORY_HEADERS ndsfactory/*.h)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
main.cpp
|
||||||
|
ui/mainwindow.cpp
|
||||||
|
${NDSFACTORY_SOURCES}
|
||||||
|
${DIALOGS_SOURCES}
|
||||||
|
${MODELS_SOURCES}
|
||||||
|
${TABS_SOURCES}
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(HEADERS
|
||||||
|
ui/mainwindow.h
|
||||||
|
${NDSFACTORY_HEADERS}
|
||||||
|
${TABS_HEADERS}
|
||||||
|
${MODELS_HEADERS}
|
||||||
|
${DIALOGS_HEADERS}
|
||||||
|
${UTILS_HEADERS}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(FORMS
|
||||||
|
ui/mainwindow.ui
|
||||||
|
${DIALOGS_UIS}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Platform-specific executable creation
|
||||||
|
if(APPLE)
|
||||||
|
set(MACOSX_BUNDLE_ICON_FILE ndsfactory.icns)
|
||||||
|
set(MACOS_ICNS "res/ndsfactory.icns")
|
||||||
|
set_source_files_properties(${MACOS_ICNS} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||||
|
add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SOURCES} ${HEADERS} ${FORMS} ${MACOS_ICNS})
|
||||||
|
elseif(WIN32)
|
||||||
|
set(WIN32_RESOURCES "res/resources.rc")
|
||||||
|
add_executable(${PROJECT_NAME} WIN32 ${SOURCES} ${HEADERS} ${FORMS} ${WIN32_RESOURCES})
|
||||||
|
else()
|
||||||
|
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${FORMS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set C++ standard for the target
|
||||||
|
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)
|
||||||
|
|
||||||
|
# Enable Qt's automatic features for the target
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
AUTOMOC ON
|
||||||
|
AUTOUIC ON
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add compile options for different compilers
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE /WX /W4 /EHsc)
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Werror)
|
||||||
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Werror)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Link the necessary Qt6 libraries
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)
|
||||||
22
CMakePresets.json
Normal file
22
CMakePresets.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"hidden": true,
|
||||||
|
"name": "Qt",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_PREFIX_PATH": "$env{QTDIR}"
|
||||||
|
},
|
||||||
|
"vendor": {
|
||||||
|
"qt-project.org/Qt": {
|
||||||
|
"checksum": "wVa86FgEkvdCTVp1/nxvrkaemJc="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vendor": {
|
||||||
|
"qt-project.org/Presets": {
|
||||||
|
"checksum": "67SmY24ZeVbebyKD0fGfIzb/bGI="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
CMakeUserPresets.json
Normal file
76
CMakeUserPresets.json
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "Qt-Debug",
|
||||||
|
"inherits": "Qt-Default",
|
||||||
|
"binaryDir": "${sourceDir}/out/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_CXX_FLAGS": "-DQT_QML_DEBUG"
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"QML_DEBUG_ARGS": "-qmljsdebugger=file:{f93ee848-589e-4ca8-9f00-8ec9e59822e9},block"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Qt-Release",
|
||||||
|
"inherits": "Qt-Default",
|
||||||
|
"binaryDir": "${sourceDir}/out/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": true,
|
||||||
|
"name": "Qt-Default",
|
||||||
|
"inherits": "6.7.2_msvc2019_64",
|
||||||
|
"vendor": {
|
||||||
|
"qt-project.org/Default": {
|
||||||
|
"checksum": "gw/ERk1cQwC3YNpVspzQ2Sww4Qk="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": true,
|
||||||
|
"name": "6.7.2_msvc2019_64",
|
||||||
|
"inherits": "Qt",
|
||||||
|
"environment": {
|
||||||
|
"QTDIR": "C:/Qt/6.7.2/msvc2019_64"
|
||||||
|
},
|
||||||
|
"architecture": {
|
||||||
|
"strategy": "external",
|
||||||
|
"value": "x64"
|
||||||
|
},
|
||||||
|
"generator": "Ninja",
|
||||||
|
"vendor": {
|
||||||
|
"qt-project.org/Version": {
|
||||||
|
"checksum": "Bix3VTiu0VJT9MULsciS2xuiRSY="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden": true,
|
||||||
|
"name": "QtDesignStudio_qt6_design_studio_reduced_version",
|
||||||
|
"inherits": "Qt",
|
||||||
|
"environment": {
|
||||||
|
"QTDIR": "C:/Qt/Tools/QtDesignStudio/qt6_design_studio_reduced_version"
|
||||||
|
},
|
||||||
|
"architecture": {
|
||||||
|
"strategy": "external",
|
||||||
|
"value": "x64"
|
||||||
|
},
|
||||||
|
"generator": "Ninja",
|
||||||
|
"vendor": {
|
||||||
|
"qt-project.org/Version": {
|
||||||
|
"checksum": "ygR+cS5HulD9XNDRlzjWPEl2jZo="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"vendor": {
|
||||||
|
"qt-project.org/Presets": {
|
||||||
|
"checksum": "Uup2yLzTIsD1yvrCY3TjhVEtXMo="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#-------------------------------------------------
|
|
||||||
#
|
|
||||||
# Project created by QtCreator 2019-08-29T12:15:45
|
|
||||||
#
|
|
||||||
#-------------------------------------------------
|
|
||||||
|
|
||||||
QT += core gui
|
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|
||||||
|
|
||||||
TARGET = NDSFactory
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
# The following define makes your compiler emit warnings if you use
|
|
||||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
|
||||||
# depend on your compiler). Please consult the documentation of the
|
|
||||||
# deprecated API in order to know how to port your code away from it.
|
|
||||||
DEFINES += QT_DEPRECATED_WARNINGS
|
|
||||||
|
|
||||||
# You can also make your code fail to compile if you use deprecated APIs.
|
|
||||||
# In order to do so, uncomment the following line.
|
|
||||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
|
||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
|
||||||
|
|
||||||
CONFIG += c++11
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
main.cpp \
|
|
||||||
mainwindow.cpp \
|
|
||||||
ndsfactory.cpp \
|
|
||||||
aboutdialog.cpp \
|
|
||||||
unpackertabfunctions.cpp \
|
|
||||||
unpackertabsignals.cpp \
|
|
||||||
packertabsignals.cpp \
|
|
||||||
packertabfunctions.cpp \
|
|
||||||
fatpatchingtabsignals.cpp \
|
|
||||||
fatpatchingtabfunctions.cpp
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
mainwindow.h \
|
|
||||||
ndsheader.h \
|
|
||||||
ndsfactory.h \
|
|
||||||
aboutdialog.h \
|
|
||||||
fatstruct.h
|
|
||||||
|
|
||||||
FORMS += \
|
|
||||||
mainwindow.ui \
|
|
||||||
aboutdialog.ui
|
|
||||||
|
|
||||||
# Default rules for deployment.
|
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
|
||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
|
||||||
!isEmpty(target.path): INSTALLS += target
|
|
||||||
43
README.md
43
README.md
@@ -3,20 +3,20 @@
|
|||||||
[](https://opensource.org/licenses/GPL-3.0/)
|
[](https://opensource.org/licenses/GPL-3.0/)
|
||||||
|
|
||||||
|
|
||||||
A tool to unpack & repack Nintendo DS roms (.nds)
|
A tool to unpack & repack Nintendo DS ROMs (.nds)
|
||||||
|
|
||||||
|
If you find this software useful, please consider supporting it:
|
||||||
If you find this software useful, please [](https://ko-fi.com/Z8Z511SOI)
|
[](https://ko-fi.com/Z8Z511SOI)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**!!!ROM WITH OVERLAY ARE CURRENTLY NOT SUPPORTED!!!**
|
**!!!ROMS WITH OVERLAY ARE CURRENTLY NOT SUPPORTED!!!**
|
||||||
|
|
||||||
# Description
|
# Description
|
||||||
|
|
||||||
This software will help you to easily unpack and repack Nintendo DS roms, but **IT REQUIRES SOME KNOWLEDGE!**
|
NDSFactory helps you easily unpack and repack Nintendo DS ROMs, but **some technical knowledge is required.**
|
||||||
|
|
||||||
Basically an NDS software is composed of the following sections:
|
A typical NDS ROM consists of the following sections:
|
||||||
* Header
|
* Header
|
||||||
* ARM9 Binary
|
* ARM9 Binary
|
||||||
* ARM7 Binary
|
* ARM7 Binary
|
||||||
@@ -27,38 +27,29 @@ Basically an NDS software is composed of the following sections:
|
|||||||
* Icon/Title Logo
|
* Icon/Title Logo
|
||||||
* FAT Files (The actual files used by the software, like Graphics, Music etc.)
|
* FAT Files (The actual files used by the software, like Graphics, Music etc.)
|
||||||
|
|
||||||
With NDSFactory you can extract these sections, modify them using your prefered way and the rebuild the rom with your edited sections.
|
NDSFactory allows you to extract these sections, modify them as needed, and rebuild the ROM with your edited sections. If modified sections are larger than the original, you must specify their new physical address and size in the header. **Ensure that sections do not overlap and remember to patch the FAT.BIN if necessary.**
|
||||||
If the modified sections are bigger than the original ones, you can specify their new physical adddress and size in the header: if so, **make
|
|
||||||
sure that they DON'T OVERLAP, and remember to PATCH THE FAT.BIN** (more on this later).
|
|
||||||
|
|
||||||
**This software will be particularly useful if you want to mod your games or write a trainer for them.**
|
This tool is particularly useful for modding games or writing trainers.
|
||||||
|
|
||||||
# How to use it
|
# How to use
|
||||||
|
|
||||||
## Unpacker Tab
|
## Unpacker Tab
|
||||||
In the upacker tab you can load your Nintendo DS software (.nds) and then you can extract the rom sections.
|
In the Unpacker Tab, you can load your Nintendo DS software (.nds) and extract the ROM sections, including individual FAT files. Take note of the original address of the FAT files, as you will need this value if you alter the addresses and sizes of the sections.
|
||||||
Please note the Original Address of the FAT Files, you will need this value later if you are going to alter the addresses and size of the sections.
|
|
||||||
|
|
||||||
**You can then do what you want with these sections (inject code, apply patches etc.)**
|
**You can then do what you want with these sections (inject code, apply patches etc.)**
|
||||||
|
|
||||||
## Packer Tab
|
## Packer Tab
|
||||||
In the packer tab you can re-create an .nds file using your edited sections. If your sections are bigger than the originals, you have to edit their addresses and size (in the header). **Make sure that the addresses don't overlap, or the final rom will be broken**. If you are repacking edited sections, and the FAT Files Address is different than the original one, **make sure to patch the FAT (fat.bin)**: the FAT is a list of absolute addresses (representing each file start adddress and end andress), so you need to update them (you can easily do this using the FAT Patching 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).
|
||||||
|
|
||||||
## Fat Patching Tab
|
## Fat Tools Tab
|
||||||
In this tab you can easily patch the FAT section (fat.bin). You have to do this only if the FAT Files (fat_data.bin) final address is different than the original one.
|
In this tab, you can 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.
|
||||||
Patching the FAT is easy, all you have to do is load your fat.bin, and fill the original address and the new address of fat_data.bin. This will produce a patched fat.bin that
|
|
||||||
you can use in the packing process.
|
|
||||||
|
|
||||||
|
# Known Limitations/Possible Future Features/Bugs
|
||||||
|
|
||||||
# Know Limitations/Possible Future Featurs/Bugs
|
* Add support for ROMs with overlays.
|
||||||
|
* Add support to rebuild a new fat_data.bin and fat.bin from a set of files inside a directory.
|
||||||
|
|
||||||
* Add support for roms with OVERLAY
|
If you find a bug, feel free to open an issue or submit a pull request :)
|
||||||
* Add support to decode FAT Files (extract single files one by one)
|
|
||||||
* Add support to rebuild a new fat_data.bin and fat.bin from a set of files inside a directory
|
|
||||||
* Design a nice logo/icon
|
|
||||||
|
|
||||||
If you found a bug, feel free to open an issue or send a PR :)
|
|
||||||
|
|
||||||
### Developed with ❤ by Luca D'Amico
|
### Developed with ❤ by Luca D'Amico
|
||||||
### Special thanks to Antonio Barba & Davide Trogu
|
### Special thanks to Antonio Barba & Davide Trogu
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
#include "aboutdialog.h"
|
|
||||||
#include "ui_aboutdialog.h"
|
|
||||||
|
|
||||||
|
|
||||||
AboutDialog::AboutDialog(QWidget *parent) :
|
|
||||||
QDialog(parent),
|
|
||||||
ui(new Ui::AboutDialog)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
AboutDialog::~AboutDialog()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#ifndef ABOUTDIALOG_H
|
|
||||||
#define ABOUTDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class AboutDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AboutDialog : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
AboutDialog(QWidget *parent = nullptr);
|
|
||||||
~AboutDialog();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::AboutDialog *ui;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // ABOUTDIALOG_H
|
|
||||||
55
cmake/sanitizers.cmake
Normal file
55
cmake/sanitizers.cmake
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Build Types
|
||||||
|
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}
|
||||||
|
CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel tsan asan lsan msan ubsan"
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
# ThreadSanitizer
|
||||||
|
set(CMAKE_C_FLAGS_TSAN
|
||||||
|
"-fsanitize=thread -g -O1"
|
||||||
|
CACHE STRING "Flags used by the C compiler during ThreadSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
set(CMAKE_CXX_FLAGS_TSAN
|
||||||
|
"-fsanitize=thread -g -O1"
|
||||||
|
CACHE STRING "Flags used by the C++ compiler during ThreadSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
# AddressSanitize
|
||||||
|
set(CMAKE_C_FLAGS_ASAN
|
||||||
|
"-fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1"
|
||||||
|
CACHE STRING "Flags used by the C compiler during AddressSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
set(CMAKE_CXX_FLAGS_ASAN
|
||||||
|
"-fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1"
|
||||||
|
CACHE STRING "Flags used by the C++ compiler during AddressSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
# LeakSanitizer
|
||||||
|
set(CMAKE_C_FLAGS_LSAN
|
||||||
|
"-fsanitize=leak -fno-omit-frame-pointer -g -O1"
|
||||||
|
CACHE STRING "Flags used by the C compiler during LeakSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
set(CMAKE_CXX_FLAGS_LSAN
|
||||||
|
"-fsanitize=leak -fno-omit-frame-pointer -g -O1"
|
||||||
|
CACHE STRING "Flags used by the C++ compiler during LeakSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
# MemorySanitizer
|
||||||
|
set(CMAKE_C_FLAGS_MSAN
|
||||||
|
"-fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2"
|
||||||
|
CACHE STRING "Flags used by the C compiler during MemorySanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
set(CMAKE_CXX_FLAGS_MSAN
|
||||||
|
"-fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g -O2"
|
||||||
|
CACHE STRING "Flags used by the C++ compiler during MemorySanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
# UndefinedBehaviour
|
||||||
|
set(CMAKE_C_FLAGS_UBSAN
|
||||||
|
"-fsanitize=undefined"
|
||||||
|
CACHE STRING "Flags used by the C compiler during UndefinedBehaviourSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
set(CMAKE_CXX_FLAGS_UBSAN
|
||||||
|
"-fsanitize=undefined"
|
||||||
|
CACHE STRING "Flags used by the C++ compiler during UndefinedBehaviourSanitizer builds."
|
||||||
|
FORCE)
|
||||||
|
|
||||||
22
main.cpp
22
main.cpp
@@ -1,11 +1,23 @@
|
|||||||
#include "mainwindow.h"
|
#include "ui/mainwindow.h"
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QStyleFactory>
|
||||||
|
#include "ui/utils/theme.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication::setStyle(QStyleFactory::create("Fusion"));
|
||||||
MainWindow w;
|
QApplication app(argc, argv);
|
||||||
w.show();
|
app.setApplicationName("NDSFactory");
|
||||||
|
app.setOrganizationName("NDSFactory");
|
||||||
|
|
||||||
return a.exec();
|
QString theme = getCurrentTheme();
|
||||||
|
if(theme == "dark")
|
||||||
|
setDarkTheme(app);
|
||||||
|
else if(theme == "light")
|
||||||
|
setLightTheme(app);
|
||||||
|
|
||||||
|
MainWindow mainWindow;
|
||||||
|
mainWindow.show();
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|||||||
2066
mainwindow.ui
2066
mainwindow.ui
File diff suppressed because it is too large
Load Diff
40
ndsfactory/crctable.h
Normal file
40
ndsfactory/crctable.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
|
static const uint16_t lCRCTable[] =
|
||||||
|
{
|
||||||
|
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
||||||
|
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
||||||
|
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
||||||
|
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
||||||
|
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
||||||
|
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
||||||
|
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
||||||
|
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
||||||
|
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
||||||
|
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
||||||
|
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
||||||
|
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
||||||
|
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
||||||
|
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
||||||
|
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
||||||
|
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
||||||
|
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
||||||
|
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
||||||
|
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
||||||
|
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
||||||
|
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
||||||
|
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
||||||
|
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
||||||
|
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
||||||
|
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
||||||
|
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
||||||
|
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
||||||
|
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
||||||
|
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
||||||
|
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
||||||
|
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
||||||
|
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
|
||||||
|
};
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef FATSTRUCT_H
|
#pragma once
|
||||||
#define FATSTRUCT_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@@ -7,5 +6,3 @@ struct FatRange {
|
|||||||
uint32_t startAddr;
|
uint32_t startAddr;
|
||||||
uint32_t endAddr;
|
uint32_t endAddr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FATSTRUCT_H
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "ndsfactory.h"
|
#include "ndsfactory.h"
|
||||||
#include "fatstruct.h"
|
#include "fatstruct.h"
|
||||||
|
#include "crctable.h"
|
||||||
|
|
||||||
|
|
||||||
NDSFactory::NDSFactory()
|
NDSFactory::NDSFactory()
|
||||||
@@ -79,6 +80,12 @@ bool NDSFactory::writeSectionToFile(const std::string& sectionPath, const std::s
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NDSFactory::writeFatSectionToFile(const std::string& romPath, FatRange* pfatrange, const std::string& savePath){
|
||||||
|
uint32_t size=pfatrange->endAddr-pfatrange->startAddr;
|
||||||
|
if(!dumpDataFromFile(romPath, savePath, pfatrange->startAddr, size)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool NDSFactory::writeBytesToFile(std::vector<char>& byteBuffer, const std::string& savePath, uint32_t startAddr, uint32_t size)
|
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);
|
std::ofstream savedFile (savePath, std::ios::out|std::ios::binary|std::ios::app);
|
||||||
@@ -109,7 +116,7 @@ bool NDSFactory::checkArm9FooterPresence(const std::string& sectionPath, uint32_
|
|||||||
std::ifstream sectionFile (sectionPath, std::ios::in|std::ios::binary|std::ios::ate);
|
std::ifstream sectionFile (sectionPath, std::ios::in|std::ios::binary|std::ios::ate);
|
||||||
if (sectionFile.is_open())
|
if (sectionFile.is_open())
|
||||||
{
|
{
|
||||||
long sectionRealSize = sectionFile.tellg();
|
std::streamoff sectionRealSize = sectionFile.tellg();
|
||||||
sectionFile.close();
|
sectionFile.close();
|
||||||
if (sectionRealSize >= size + Arm9FooterSize)
|
if (sectionRealSize >= size + Arm9FooterSize)
|
||||||
{
|
{
|
||||||
@@ -127,8 +134,8 @@ bool NDSFactory::patchFat(const std::string& fatSectionPath, uint32_t shiftSize,
|
|||||||
if (!sectionFile.is_open())
|
if (!sectionFile.is_open())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
long sectionSize = sectionFile.tellg();
|
std::streamoff sectionSize = sectionFile.tellg();
|
||||||
fatBytes.resize(static_cast<unsigned long>(sectionSize));
|
fatBytes.resize(sectionSize);
|
||||||
|
|
||||||
sectionFile.seekg (0, std::ios::beg);
|
sectionFile.seekg (0, std::ios::beg);
|
||||||
|
|
||||||
@@ -145,3 +152,21 @@ bool NDSFactory::patchFat(const std::string& fatSectionPath, uint32_t shiftSize,
|
|||||||
|
|
||||||
return writeBytesToFile(fatBytes, savePath, 0, static_cast<uint32_t>(sectionSize));
|
return writeBytesToFile(fatBytes, savePath, 0, static_cast<uint32_t>(sectionSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t NDSFactory::calcHeaderCrc16(const std::vector<char>& romHeader)
|
||||||
|
{
|
||||||
|
uint8_t loc;
|
||||||
|
uint16_t crc = 0xFFFF;
|
||||||
|
size_t size = 0x15E;
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
loc = static_cast<unsigned char>(romHeader[index] ^ crc);
|
||||||
|
index++;
|
||||||
|
crc >>= 8;
|
||||||
|
crc ^= lCRCTable[loc];
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#ifndef NDSFACTORY_H
|
#pragma once
|
||||||
#define NDSFACTORY_H
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "ndsheader.h"
|
#include "ndsheader.h"
|
||||||
|
#include "fatstruct.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -16,14 +16,15 @@ public:
|
|||||||
bool dumpDataFromFile(const std::string& romPath, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
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 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 writeSectionToFile(const std::string& sectionPath, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||||
|
bool writeFatSectionToFile(const std::string& romPath, FatRange* pfatrange, const std::string& savePath);
|
||||||
bool writeBytesToFile(std::vector<char>& byteBuffer, 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);
|
bool writePaddingToFile(char paddingChar, const std::string& savePath, uint32_t startAddr, uint32_t size);
|
||||||
int getCardSizeInBytes(int cardType);
|
int getCardSizeInBytes(int cardType);
|
||||||
bool checkArm9FooterPresence(const std::string& sectionPath, uint32_t size);
|
bool checkArm9FooterPresence(const std::string& sectionPath, uint32_t size);
|
||||||
bool patchFat(const std::string& sectionPath, uint32_t shiftSize, const std::string& savePath);
|
bool patchFat(const std::string& sectionPath, uint32_t shiftSize, const std::string& savePath);
|
||||||
|
uint16_t calcHeaderCrc16(const std::vector<char>& romHeader);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NDSFACTORY_H
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
#ifndef NDSHEADER_H
|
#pragma once
|
||||||
#define NDSHEADER_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
@@ -69,6 +68,3 @@ struct NDSHeader
|
|||||||
unsigned char Reserved4[0x90];
|
unsigned char Reserved4[0x90];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
#endif // NDSHEADER_H
|
|
||||||
@@ -1,353 +0,0 @@
|
|||||||
#include <QDir>
|
|
||||||
#include <cstring>
|
|
||||||
#include <algorithm>
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::populatePackerSectionHeader(NDSHeader *ndsHeader)
|
|
||||||
{
|
|
||||||
ui->packerGameTitleEdt->setText(QString::fromUtf8(ndsHeader->GameTitle, 0xC));
|
|
||||||
ui->packerGameCodeEdt->setText(QString::fromUtf8(ndsHeader->GameCode, 0x4));
|
|
||||||
ui->packerMakerCodeEdt->setText(QString::fromUtf8(reinterpret_cast<char*>(ndsHeader->MakerCode), 0x2));
|
|
||||||
ui->packerUnitCodeEdt->setText(QString::number(ndsHeader->UnitCode, 16));
|
|
||||||
|
|
||||||
ui->packerDeviceCodeEdt->setText(QString::number(ndsHeader->DeviceType, 16));
|
|
||||||
ui->packerCardSizeEdt->setText(QString::number(ndsHeader->DeviceSize, 16));
|
|
||||||
ui->packerCardInfoEdt->setText(QString::number(ndsHeader->RomVersion, 16));
|
|
||||||
ui->packerFlagsEdt->setText(QString::number(ndsHeader->Flags, 16));
|
|
||||||
|
|
||||||
ui->packerARM9RomAddrEdt->setText(QString::number(ndsHeader->Arm9RomAddr, 16));
|
|
||||||
ui->packerARM9EntryAddrEdt->setText(QString::number(ndsHeader->Arm9EntryAddr, 16));
|
|
||||||
ui->packerARM9RamAddrEdt->setText(QString::number(ndsHeader->Arm9RamAddr, 16));
|
|
||||||
ui->packerARM9SizeEdt->setText(QString::number(ndsHeader->Arm9Size, 16));
|
|
||||||
|
|
||||||
ui->packerARM7RomAddrEdt->setText(QString::number(ndsHeader->Arm7RomAddr, 16));
|
|
||||||
ui->packerARM7EntryAddrEdt->setText(QString::number(ndsHeader->Arm7EntryAddr, 16));
|
|
||||||
ui->packerARM7RamAddrEdt->setText(QString::number(ndsHeader->Arm7RamAddr, 16));
|
|
||||||
ui->packerARM7SizeEdt->setText(QString::number(ndsHeader->Arm7Size, 16));
|
|
||||||
|
|
||||||
ui->packerFilenameTableAddrEdt->setText(QString::number(ndsHeader->FilenameTableAddr, 16));
|
|
||||||
ui->packerFilenameTableSizeEdt->setText(QString::number(ndsHeader->FilenameSize, 16));
|
|
||||||
ui->packerFATAddrEdt->setText(QString::number(ndsHeader->FATAddr, 16));
|
|
||||||
ui->packerFATSizeEdt->setText(QString::number(ndsHeader->FATSize, 16));
|
|
||||||
|
|
||||||
ui->packerARM9OverlayAddrEdt->setText(QString::number(ndsHeader->Arm9OverlayAddr, 16));
|
|
||||||
ui->packerARM9OverlaySizeEdt->setText(QString::number(ndsHeader->Arm9OverlaySize, 16));
|
|
||||||
ui->packerARM7OverlayAddrEdt->setText(QString::number(ndsHeader->Arm7OverlayAddr, 16));
|
|
||||||
ui->packerARM7OverlaySizeEdt->setText(QString::number(ndsHeader->Arm7OverlaySize, 16));
|
|
||||||
|
|
||||||
ui->packerPortNCEdt->setText(QString::number(ndsHeader->NormalCommandsSettings, 16));
|
|
||||||
ui->packerPortKCEdt->setText(QString::number(ndsHeader->Key1CommandsSettings, 16));
|
|
||||||
ui->packerIconTitleEdt->setText(QString::number(ndsHeader->IconTitleAddr, 16));
|
|
||||||
ui->packerSecureAreaCRC16Edt->setText(QString::number(ndsHeader->SecureAreaCRC16, 16));
|
|
||||||
|
|
||||||
ui->packerSecureAreaTimeoutEdt->setText(QString::number(ndsHeader->SecureAreaLoadingTimeout, 16));
|
|
||||||
ui->packerARM9AURamAddrEdt->setText(QString::number(ndsHeader->ARM9AutoLoadListRamAddr, 16));
|
|
||||||
ui->packerARM7AURamAddrEdt->setText(QString::number(ndsHeader->ARM7AutoLoadListRamAddr, 16));
|
|
||||||
ui->packerSecureAreaDisableEdt->setText(QString::number(ndsHeader->SecureAreaDisable, 16));
|
|
||||||
|
|
||||||
ui->packerUsedRomSizeEdt->setText(QString::number(ndsHeader->RomSize, 16));
|
|
||||||
ui->packerHeaderSizeEdt->setText(QString::number(ndsHeader->HeaderSize, 16));
|
|
||||||
ui->packerNintendoLogoEdt->setText(QByteArray::fromRawData(reinterpret_cast<char*>(ndsHeader->NintendoLogo), 0x9C).toHex());
|
|
||||||
ui->packerNintendoLogoCRCEdt->setText(QString::number(ndsHeader->NintendoLogoCRC, 16));
|
|
||||||
|
|
||||||
ui->packerHeaderCRCEdt->setText(QString::number(ndsHeader->HeaderCRC16, 16));
|
|
||||||
ui->packerDebugRomAddrEdt->setText(QString::number(ndsHeader->DebugRomAddr, 16));
|
|
||||||
ui->packerDebugSizeEdt->setText(QString::number(ndsHeader->DebugSize, 16));
|
|
||||||
ui->packerDebugRamAddrEdt->setText(QString::number(ndsHeader->DebugRamAddr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool MainWindow::writeHeader(const std::string& savePath)
|
|
||||||
{
|
|
||||||
std::vector<char> romHeader(sizeof(NDSHeader));
|
|
||||||
NDSHeader* pRomHeader = reinterpret_cast<NDSHeader*>(romHeader.data());
|
|
||||||
|
|
||||||
std::copy_n(ui->packerGameTitleEdt->text().toLatin1().data(), 0xc, std::begin(pRomHeader->GameTitle));
|
|
||||||
std::copy_n(ui->packerGameCodeEdt->text().toStdString().data(), 0x4, std::begin(pRomHeader->GameCode));
|
|
||||||
std::copy_n(ui->packerMakerCodeEdt->text().toStdString().data(), 0x2, std::begin(pRomHeader->MakerCode));
|
|
||||||
pRomHeader->UnitCode = static_cast<unsigned char>(ui->packerUnitCodeEdt->text().toUInt(nullptr, 16));
|
|
||||||
|
|
||||||
pRomHeader->DeviceType = static_cast<unsigned char>(ui->packerDeviceCodeEdt->text().toUInt(nullptr, 16));
|
|
||||||
pRomHeader->DeviceSize = static_cast<unsigned char>(ui->packerCardSizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
|
|
||||||
std::fill(std::begin(pRomHeader->Reserved1), std::end(pRomHeader->Reserved1), 0);
|
|
||||||
|
|
||||||
pRomHeader->RomVersion = static_cast<unsigned char>(ui->packerCardInfoEdt->text().toUInt(nullptr, 16));
|
|
||||||
pRomHeader->Flags = static_cast<unsigned char>(ui->packerFlagsEdt->text().toUInt(nullptr, 16));
|
|
||||||
|
|
||||||
pRomHeader->Arm9RomAddr = ui->packerARM9RomAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm9EntryAddr = ui->packerARM9EntryAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm9RamAddr = ui->packerARM9RamAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm9Size = ui->packerARM9SizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->Arm7RomAddr = ui->packerARM7RomAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm7EntryAddr = ui->packerARM7EntryAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm7RamAddr = ui->packerARM7RamAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm7Size = ui->packerARM7SizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->FilenameTableAddr = ui->packerFilenameTableAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->FilenameSize = ui->packerFilenameTableSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->FATAddr = ui->packerFATAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->FATSize = ui->packerFATSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->Arm9OverlayAddr = ui->packerARM9OverlayAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm9OverlaySize = ui->packerARM9OverlaySizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm7OverlayAddr = ui->packerARM7OverlayAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Arm7OverlaySize = ui->packerARM7OverlaySizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->NormalCommandsSettings = ui->packerPortNCEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->Key1CommandsSettings = ui->packerPortKCEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->IconTitleAddr = ui->packerIconTitleEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->SecureAreaCRC16 = ui->packerSecureAreaCRC16Edt->text().toUShort(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->SecureAreaLoadingTimeout = ui->packerSecureAreaTimeoutEdt->text().toUShort(nullptr, 16);
|
|
||||||
pRomHeader->ARM9AutoLoadListRamAddr = ui->packerARM9AURamAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->ARM7AutoLoadListRamAddr = ui->packerARM7AURamAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->SecureAreaDisable = ui->packerSecureAreaDisableEdt->text().toULong(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->RomSize = ui->packerUsedRomSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->HeaderSize = ui->packerHeaderSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
|
|
||||||
std::fill(std::begin(pRomHeader->Reserved2), std::end(pRomHeader->Reserved2), 0);
|
|
||||||
std::copy_n(std::begin(QByteArray::fromHex(ui->packerNintendoLogoEdt->text().toUtf8())), 0x9C, std::begin(pRomHeader->NintendoLogo));
|
|
||||||
pRomHeader->NintendoLogoCRC = ui->packerNintendoLogoCRCEdt->text().toUShort(nullptr, 16);
|
|
||||||
|
|
||||||
pRomHeader->HeaderCRC16 = ui->packerHeaderCRCEdt->text().toUShort(nullptr, 16);
|
|
||||||
pRomHeader->DebugRomAddr = ui->packerDebugRomAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->DebugSize = ui->packerDebugSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
pRomHeader->DebugRamAddr = ui->packerDebugRamAddrEdt->text().toUInt(nullptr, 16);
|
|
||||||
|
|
||||||
std::fill(std::begin(pRomHeader->Reserved3), std::end(pRomHeader->Reserved3), 0);
|
|
||||||
std::fill(std::begin(pRomHeader->Reserved4), std::end(pRomHeader->Reserved4), 0);
|
|
||||||
|
|
||||||
return ndsFactory.writeBytesToFile(romHeader, savePath, 0, sizeof(NDSHeader));;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent)
|
|
||||||
{
|
|
||||||
uint32_t size = ui->packerARM9SizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
if (isArm9FooterPresent)
|
|
||||||
size += Arm9FooterSize;
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedArm9BinPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerARM9RomAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm7Bin(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedArm7BinPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerARM7RomAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->packerARM7SizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeFnt(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedFntPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerFilenameTableAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->packerFilenameTableSizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeFat(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedFatPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerFATAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->packerFATSizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm9Overlay(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedArm9OverlayPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerARM9OverlayAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->packerARM9OverlaySizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm9OverlayFiles(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return false; // TODO: implement me!
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm7Overlay(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedArm7OverlayPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerARM7OverlayAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->packerARM7OverlaySizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm7OverlayFiles(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return false; // TODO: implement me!
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeIconTitle(const std::string& savePath)
|
|
||||||
{
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedIconTitlePathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
ui->packerIconTitleEdt->text().toUInt(nullptr, 16),
|
|
||||||
IconTitleSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeFatFiles(const std::string& savePath)
|
|
||||||
{
|
|
||||||
uint32_t startAddr = ui->packerIconTitleEdt->text().toUInt(nullptr, 16) + IconTitleSize;
|
|
||||||
uint32_t size = ui->packerUsedRomSizeEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.writeSectionToFile(
|
|
||||||
ui->loadedFatFilesPathEdt->text().toStdString(),
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeHeaderPadding(char paddingType, const std::string& savePath)
|
|
||||||
{
|
|
||||||
uint32_t startAddr = sizeof(NDSHeader);
|
|
||||||
uint32_t size = ui->packerARM9RomAddrEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.writePaddingToFile(
|
|
||||||
paddingType,
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm9BinPadding(char paddingType, const std::string& savePath, bool isFooterPresent)
|
|
||||||
{ // FIXME check ARM9 Overlay
|
|
||||||
uint32_t startAddr = ui->packerARM9RomAddrEdt->text().toUInt(nullptr, 16) + ui->packerARM9SizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
uint32_t size = ui->packerARM7RomAddrEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
if (isFooterPresent)
|
|
||||||
size -= Arm9FooterSize;
|
|
||||||
|
|
||||||
return ndsFactory.writePaddingToFile(
|
|
||||||
paddingType,
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm7BinPadding(char paddingType, const std::string& savePath)
|
|
||||||
{ // FIXME check ARM7 Overlay
|
|
||||||
uint32_t startAddr = ui->packerARM7RomAddrEdt->text().toUInt(nullptr, 16) + ui->packerARM7SizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
uint32_t size = ui->packerFilenameTableAddrEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.writePaddingToFile(
|
|
||||||
paddingType,
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeFntPadding(char paddingType, const std::string& savePath)
|
|
||||||
{
|
|
||||||
uint32_t startAddr = ui->packerFilenameTableAddrEdt->text().toUInt(nullptr, 16) + ui->packerFilenameTableSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
uint32_t size = ui->packerFATAddrEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.writePaddingToFile(
|
|
||||||
paddingType,
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeFatPadding(char paddingType, const std::string& savePath)
|
|
||||||
{
|
|
||||||
uint32_t startAddr = ui->packerFATAddrEdt->text().toUInt(nullptr, 16) + ui->packerFATSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
uint32_t size = ui->packerIconTitleEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.writePaddingToFile(
|
|
||||||
paddingType,
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm9OverlayPadding(char paddingType, const std::string& savePath)
|
|
||||||
{ // FIXME TODO
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm9OverlayFilesPadding(char paddingType, const std::string& savePath)
|
|
||||||
{ // FIXME TODO
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeArm7OverlayPadding(char paddingType, const std::string& savePath)
|
|
||||||
{ // FIXME TODO
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool MainWindow::writeArm7OverlayFilesPadding(char paddingType, const std::string& savePath)
|
|
||||||
{ // FIXME TODO
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::writeRomPadding(const std::string& savePath)
|
|
||||||
{
|
|
||||||
uint32_t startAddr = ui->packerUsedRomSizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
uint32_t size = static_cast<uint32_t>(ndsFactory.getCardSizeInBytes(ui->packerCardSizeEdt->text().toInt())) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.writePaddingToFile(
|
|
||||||
static_cast<char>('\xff'),
|
|
||||||
savePath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool MainWindow::writeEverything(const std::string& savePath)
|
|
||||||
{
|
|
||||||
bool res = true;
|
|
||||||
char paddingType;
|
|
||||||
bool isArm9FooterPresent = ndsFactory.checkArm9FooterPresence(ui->loadedArm9BinPathEdt->text().toStdString(),
|
|
||||||
ui->packerARM9SizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
if (ui->packerPadType00RdBtn->isChecked())
|
|
||||||
paddingType = static_cast<char>('\x00');
|
|
||||||
else
|
|
||||||
paddingType = static_cast<char>('\xff');
|
|
||||||
|
|
||||||
res &= writeHeader(savePath);
|
|
||||||
res &= writeHeaderPadding(paddingType, savePath);
|
|
||||||
res &= writeArm9Bin(savePath, isArm9FooterPresent);
|
|
||||||
res &= writeArm9BinPadding(paddingType, savePath, isArm9FooterPresent);
|
|
||||||
res &= writeArm7Bin(savePath);
|
|
||||||
res &= writeArm7BinPadding(paddingType, savePath);
|
|
||||||
res &= writeFnt(savePath);
|
|
||||||
res &= writeFntPadding(paddingType, savePath);
|
|
||||||
res &= writeFat(savePath);
|
|
||||||
res &= writeFatPadding(paddingType, savePath);
|
|
||||||
if(ui->packerARM9OverlayAddrEdt->text().toUInt(nullptr, 16) != 0) {
|
|
||||||
res &= writeArm9Overlay(savePath);
|
|
||||||
res &= writeArm9OverlayPadding(paddingType, savePath);
|
|
||||||
res &= writeArm9OverlayFiles(savePath);
|
|
||||||
res &= writeArm9OverlayFilesPadding(paddingType, savePath);
|
|
||||||
}
|
|
||||||
if(ui->packerARM7OverlayAddrEdt->text().toUInt(nullptr, 16) != 0) {
|
|
||||||
res &= writeArm7Overlay(savePath);
|
|
||||||
res &= writeArm7OverlayPadding(paddingType, savePath);
|
|
||||||
res &= writeArm7OverlayFiles(savePath);
|
|
||||||
res &= writeArm7OverlayFilesPadding(paddingType, savePath);
|
|
||||||
}
|
|
||||||
res &= writeIconTitle(savePath);
|
|
||||||
res &= writeFatFiles(savePath);
|
|
||||||
if(!ui->packerTrimRomsCbx->isChecked())
|
|
||||||
{
|
|
||||||
res &= writeRomPadding(savePath);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
BIN
res/ndsfactory.icns
Normal file
BIN
res/ndsfactory.icns
Normal file
Binary file not shown.
BIN
res/ndsfactory.ico
Normal file
BIN
res/ndsfactory.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
1
res/resources.rc
Normal file
1
res/resources.rc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
IDI_ICON1 ICON "ndsfactory.ico"
|
||||||
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 62 KiB |
21
ui/dialogs/about/aboutdialog.cpp
Normal file
21
ui/dialogs/about/aboutdialog.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "aboutdialog.h"
|
||||||
|
#include "ui_aboutdialog.h"
|
||||||
|
#include "revision.h"
|
||||||
|
|
||||||
|
|
||||||
|
AboutDialog::AboutDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::AboutDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
QString currentVersion = ui->aboutSoftwareNameLbl->text();
|
||||||
|
QString currentRevision = QString("Rev: %1").arg(GIT_COMMIT_HASH);
|
||||||
|
ui->aboutSoftwareNameLbl->setText(currentVersion + " " + currentRevision);
|
||||||
|
QString buildInfo = QString("Build Date: %1 Time: %2").arg(__DATE__, __TIME__);
|
||||||
|
ui->aboutSoftwareBuildLbl->setText(buildInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDialog::~AboutDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
19
ui/dialogs/about/aboutdialog.h
Normal file
19
ui/dialogs/about/aboutdialog.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AboutDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AboutDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AboutDialog(QWidget *parent = nullptr);
|
||||||
|
~AboutDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AboutDialog *ui;
|
||||||
|
|
||||||
|
};
|
||||||
@@ -7,33 +7,33 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>300</height>
|
<height>179</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>About</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QDialogButtonBox" name="aboutCloseBtnBx">
|
<widget class="QDialogButtonBox" name="aboutCloseBtnBx">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>300</x>
|
<x>300</x>
|
||||||
<y>260</y>
|
<y>140</y>
|
||||||
<width>81</width>
|
<width>81</width>
|
||||||
<height>32</height>
|
<height>32</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::StandardButton::Ok</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="aboutSoftwareNameLbl">
|
<widget class="QLabel" name="aboutSoftwareNameLbl">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>150</y>
|
<y>20</y>
|
||||||
<width>381</width>
|
<width>381</width>
|
||||||
<height>31</height>
|
<height>31</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -42,33 +42,33 @@
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>NDS Factory V1.0</string>
|
<string>NDS Factory V1.1</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="aboutSoftwareAuthorLbl">
|
<widget class="QLabel" name="aboutSoftwareAuthorLbl">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>180</y>
|
<y>70</y>
|
||||||
<width>381</width>
|
<width>381</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>(C) 2019 - Luca D'Amico</string>
|
<string>(C) 2019-2024 - Luca D'Amico</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="aboutSpecialThanks">
|
<widget class="QLabel" name="aboutSpecialThanks">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>200</y>
|
<y>90</y>
|
||||||
<width>381</width>
|
<width>381</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -77,14 +77,14 @@
|
|||||||
<string>Special Thanks To:</string>
|
<string>Special Thanks To:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="aboutSpecialThanks2ndLine">
|
<widget class="QLabel" name="aboutSpecialThanks2ndLine">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>220</y>
|
<y>110</y>
|
||||||
<width>381</width>
|
<width>381</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -93,7 +93,23 @@
|
|||||||
<string>Dax89 (Davide Trogu) & Kaneb (Antonio Barba)</string>
|
<string>Dax89 (Davide Trogu) & Kaneb (Antonio Barba)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignCenter</set>
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="aboutSoftwareBuildLbl">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>50</y>
|
||||||
|
<width>381</width>
|
||||||
|
<height>20</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Build Info</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
6
ui/dialogs/about/revision.h
Normal file
6
ui/dialogs/about/revision.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef REVISION_H
|
||||||
|
#define REVISION_H
|
||||||
|
|
||||||
|
#define GIT_COMMIT_HASH "aa2ed50"
|
||||||
|
|
||||||
|
#endif
|
||||||
6
ui/dialogs/about/revision.h.in
Normal file
6
ui/dialogs/about/revision.h.in
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef REVISION_H
|
||||||
|
#define REVISION_H
|
||||||
|
|
||||||
|
#define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
#include <QApplication>
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "aboutdialog.h"
|
|
||||||
#include "ui_mainwindow.h"
|
#include "ui_mainwindow.h"
|
||||||
|
#include "dialogs/about/aboutdialog.h"
|
||||||
|
#include "utils/theme.h"
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
@@ -25,3 +27,18 @@ void MainWindow::on_actionAbout_triggered()
|
|||||||
AboutDialog aboutDialog;
|
AboutDialog aboutDialog;
|
||||||
aboutDialog.exec();
|
aboutDialog.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionDark_triggered()
|
||||||
|
{
|
||||||
|
setTheme("dark");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionLight_triggered()
|
||||||
|
{
|
||||||
|
setTheme("light");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_actionDefault_triggered()
|
||||||
|
{
|
||||||
|
setTheme("default");
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
#ifndef MAINWINDOW_H
|
#pragma once
|
||||||
#define MAINWINDOW_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "ndsfactory.h"
|
#include "../ndsfactory/ndsfactory.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@@ -33,7 +32,11 @@ private slots:
|
|||||||
void on_unpackerDumpArm7OverlayFilesBtn_clicked();
|
void on_unpackerDumpArm7OverlayFilesBtn_clicked();
|
||||||
void on_unpackerDumpEverythingBtn_clicked();
|
void on_unpackerDumpEverythingBtn_clicked();
|
||||||
void on_unpackerDecodeFatFilesBtn_clicked();
|
void on_unpackerDecodeFatFilesBtn_clicked();
|
||||||
|
void notifyExtractionResult(bool result);
|
||||||
|
|
||||||
|
void on_actionDark_triggered();
|
||||||
|
void on_actionLight_triggered();
|
||||||
|
void on_actionDefault_triggered();
|
||||||
void on_actionExit_triggered();
|
void on_actionExit_triggered();
|
||||||
void on_actionAbout_triggered();
|
void on_actionAbout_triggered();
|
||||||
|
|
||||||
@@ -50,13 +53,16 @@ private slots:
|
|||||||
void on_packerLoadFatFilesBtn_clicked();
|
void on_packerLoadFatFilesBtn_clicked();
|
||||||
void on_packerBuildNDSRomBtn_clicked();
|
void on_packerBuildNDSRomBtn_clicked();
|
||||||
|
|
||||||
void on_fatPatchingLoadFatBtn_clicked();
|
void on_fatPatcherLoadFatBtn_clicked();
|
||||||
|
|
||||||
void on_fatPatchingPatchFatBtn_clicked();
|
void on_fatPatcherPatchFatBtn_clicked();
|
||||||
|
|
||||||
|
void on_packerCalcHeaderCrcBtn_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
NDSFactory ndsFactory;
|
NDSFactory ndsFactory;
|
||||||
|
std::vector<char> romHeader;
|
||||||
void populateHeader(NDSHeader* ndsHeader);
|
void populateHeader(NDSHeader* ndsHeader);
|
||||||
void enableExtractionButtons();
|
void enableExtractionButtons();
|
||||||
void disableExtractionButtons();
|
void disableExtractionButtons();
|
||||||
@@ -74,7 +80,11 @@ private:
|
|||||||
bool dumpEverything(QString dirPath);
|
bool dumpEverything(QString dirPath);
|
||||||
|
|
||||||
void populatePackerSectionHeader(NDSHeader *ndsHeader);
|
void populatePackerSectionHeader(NDSHeader *ndsHeader);
|
||||||
|
void enableCalcCrcButton();
|
||||||
|
void enableBuildRomButton();
|
||||||
|
void generateHeader(NDSHeader* pRomHeader);
|
||||||
bool writeHeader(const std::string& savePath);
|
bool writeHeader(const std::string& savePath);
|
||||||
|
void calcHeaderCrc16();
|
||||||
bool writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent);
|
bool writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent);
|
||||||
bool writeArm7Bin(const std::string& savePath);
|
bool writeArm7Bin(const std::string& savePath);
|
||||||
bool writeFnt(const std::string& savePath);
|
bool writeFnt(const std::string& savePath);
|
||||||
@@ -98,9 +108,10 @@ private:
|
|||||||
bool writeArm7OverlayFilesPadding(char paddingByte, const std::string& savePath);
|
bool writeArm7OverlayFilesPadding(char paddingByte, const std::string& savePath);
|
||||||
bool writeRomPadding(const std::string& savePath);
|
bool writeRomPadding(const std::string& savePath);
|
||||||
|
|
||||||
bool decodeFatFiles();
|
//QString extractUnpackerHeaderTableData(int index);
|
||||||
|
QString extractPackerHeaderTableData(int index);
|
||||||
|
|
||||||
|
bool decodeFatFiles(QString dirPath);
|
||||||
|
|
||||||
bool patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath);
|
bool patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
|
||||||
821
ui/mainwindow.ui
Normal file
821
ui/mainwindow.ui
Normal file
@@ -0,0 +1,821 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>770</width>
|
||||||
|
<height>844</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>NDSFactory</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralWidget">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>756</width>
|
||||||
|
<height>800</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinAndMaxSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="mainTab">
|
||||||
|
<property name="locale">
|
||||||
|
<locale language="English" country="UnitedStates"/>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="unpackerTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Unpacker</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>Rom</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedRomPath">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="loadRomBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load Rom</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Header</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="unpackerHeaderDataTable">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Tools</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="unpackerExtractorGbx">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Single Binary Extractor</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpHeaderBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Header</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpArm9Btn">
|
||||||
|
<property name="text">
|
||||||
|
<string>ARM9 Bin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpArm7Btn">
|
||||||
|
<property name="text">
|
||||||
|
<string>ARM7 Bin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpFntBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filename Table</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpFatBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>FAT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpFatFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>FAT Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpArm9OverlayBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>ARM9 Overlay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpArm9OverlayFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>ARM9 Overlay Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>7</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpArm7OverlayBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>ARM7 Overlay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpArm7OverlayFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>ARM7 Overlay Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpIconTitleLogoBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Icon/Title Logo</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="unpackerExtraGbx">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>AIO</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDumpEverythingBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Extract Everything</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="unpackerDecodeFatFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Decode FAT Contents</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="packerTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Packer</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Header</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QTableView" name="packerHeaderDataTable">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::EditTrigger::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_33">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerCalcHeaderCrcBtn">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Calc Header CRC</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadHeaderBtn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LayoutDirection::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import Header From File</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="unpackerInjectorGbx">
|
||||||
|
<property name="title">
|
||||||
|
<string>Injector</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedArm9BinPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadArm9BinBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load Arm9 Bin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedArm7BinPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadArm7BinBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load Arm7 Bin</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_28">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedFntPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadFntBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load FNT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedFatPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadFatBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load FAT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_29">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedArm9OverlayPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadArm9OverlayBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load ARM9 Overlay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedArm9OverlayFilesPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadArm9OverlayFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load ARM9 Overlay Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_30">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedArm7OverlayPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadArm7OverlayBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load ARM7 Overlay</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedArm7OverlayFilesPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadArm7OverlayFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load ARM7 Overlay Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_31">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedIconTitlePathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadIconTitleBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load Icon/Title</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="loadedFatFilesPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerLoadFatFilesBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load FAT Files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_5">
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LayoutDirection::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Builder</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_32">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="packerPadType00RdBtn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PAD Sections With 00s</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="packerPadTypeFFRdBtn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PAD Sections With FFs</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="packerTrimRomsCbx">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LayoutDirection::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Generate Trimmed Rom</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="packerBuildNDSRomBtn">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Build NDS Rom</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="fatToolsTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Fat Tools</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
|
<property name="title">
|
||||||
|
<string>FAT Patcher</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_83">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>If the address of the fat_data.bin file is different from the original location in ROM, you need to patch the fat.bin file...</string>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_35">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="fatPatcherFatPathEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="fatPatcherLoadFatBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Load FAT (fat.bin)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_36">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_84">
|
||||||
|
<property name="text">
|
||||||
|
<string>Original Fat Files (fat_data.bin) Addr:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="fatPatcherOriginalFatFilesAddrEdt"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_85">
|
||||||
|
<property name="text">
|
||||||
|
<string>New Fat Files Addr:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="fatPatcherNewFatFilesAddrEdt"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_37">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="fatPatcherPatchFatBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Apply Patch!</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menuBar">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>770</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menuTheme">
|
||||||
|
<property name="title">
|
||||||
|
<string>Theme</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionDark"/>
|
||||||
|
<addaction name="actionLight"/>
|
||||||
|
<addaction name="actionDefault"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuTheme"/>
|
||||||
|
<addaction name="actionExit"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuHelp">
|
||||||
|
<property name="title">
|
||||||
|
<string>Help</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionAbout"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuHelp"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusBar">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<action name="actionAbout">
|
||||||
|
<property name="text">
|
||||||
|
<string>About</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionExit">
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDark">
|
||||||
|
<property name="text">
|
||||||
|
<string>Dark</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionLight">
|
||||||
|
<property name="text">
|
||||||
|
<string>Light</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionDefault">
|
||||||
|
<property name="text">
|
||||||
|
<string>Default</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
190
ui/models/ndsheadermodel.cpp
Normal file
190
ui/models/ndsheadermodel.cpp
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
#include <QMessageBox>
|
||||||
|
#include "ndsheadermodel.h"
|
||||||
|
#include "../../ndsfactory/ndsheader.h"
|
||||||
|
#include "../tabs/commons/headernames.h"
|
||||||
|
|
||||||
|
|
||||||
|
NDSHeaderModel::NDSHeaderModel(NDSHeader *ndsHeader, QObject *parent) : QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
this->ndsHeader = ndsHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NDSHeaderModel::rowCount([[maybe_unused]] const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return static_cast<int>(ndsHeaderNamesArr.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
int NDSHeaderModel::columnCount([[maybe_unused]] const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant NDSHeaderModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole || role == Qt::EditRole)
|
||||||
|
{
|
||||||
|
if(index.column() == 0)
|
||||||
|
return QString::fromStdString(ndsHeaderNamesArr.at(static_cast<size_t>(index.row())));
|
||||||
|
else if(index.column() == 1) {
|
||||||
|
switch (index.row())
|
||||||
|
{
|
||||||
|
case 0: return QString::fromUtf8(ndsHeader->GameTitle, 0xC);
|
||||||
|
case 1: return QString::fromUtf8(ndsHeader->GameCode, 0x4);
|
||||||
|
case 2: return QString::fromUtf8(reinterpret_cast<char*>(ndsHeader->MakerCode), 0x2);
|
||||||
|
case 3: return QString::number(ndsHeader->UnitCode, 16);
|
||||||
|
case 4: return QString::number(ndsHeader->DeviceType, 16);
|
||||||
|
case 5: return QString::number(ndsHeader->DeviceSize, 16);
|
||||||
|
case 6: return QString::number(ndsHeader->RomVersion, 16);
|
||||||
|
case 7: return QString::number(ndsHeader->Flags, 16);
|
||||||
|
case 8: return QString::number(ndsHeader->Arm9RomAddr,16);
|
||||||
|
case 9: return QString::number(ndsHeader->Arm9EntryAddr,16);
|
||||||
|
case 10: return QString::number(ndsHeader->Arm9RamAddr,16);
|
||||||
|
case 11: return QString::number(ndsHeader->Arm9Size,16);
|
||||||
|
case 12: return QString::number(ndsHeader->Arm7RomAddr,16);
|
||||||
|
case 13: return QString::number(ndsHeader->Arm7EntryAddr,16);
|
||||||
|
case 14: return QString::number(ndsHeader->Arm7RamAddr,16);
|
||||||
|
case 15: return QString::number(ndsHeader->Arm7Size,16);
|
||||||
|
case 16: return QString::number(ndsHeader->FilenameTableAddr,16);
|
||||||
|
case 17: return QString::number(ndsHeader->FilenameSize,16);
|
||||||
|
case 18: return QString::number(ndsHeader->FATAddr,16);
|
||||||
|
case 19: return QString::number(ndsHeader->FATSize,16);
|
||||||
|
case 20: return QString::number(ndsHeader->Arm9OverlayAddr,16);
|
||||||
|
case 21: return QString::number(ndsHeader->Arm9OverlaySize,16);
|
||||||
|
case 22: return QString::number(ndsHeader->Arm7OverlayAddr,16);
|
||||||
|
case 23: return QString::number(ndsHeader->Arm7OverlaySize,16);
|
||||||
|
case 24: return QString::number(ndsHeader->NormalCommandsSettings,16);
|
||||||
|
case 25: return QString::number(ndsHeader->Key1CommandsSettings,16);
|
||||||
|
case 26: return QString::number(ndsHeader->IconTitleAddr,16);
|
||||||
|
case 27: return QString::number(ndsHeader->SecureAreaCRC16,16);
|
||||||
|
case 28: return QString::number(ndsHeader->SecureAreaLoadingTimeout,16);
|
||||||
|
case 29: return QString::number(ndsHeader->ARM9AutoLoadListRamAddr,16);
|
||||||
|
case 30: return QString::number(ndsHeader->ARM7AutoLoadListRamAddr,16);
|
||||||
|
case 31: return QString::number(ndsHeader->SecureAreaDisable,16);
|
||||||
|
case 32: return QString::number(ndsHeader->RomSize,16);
|
||||||
|
case 33: return QString::number(ndsHeader->HeaderSize,16);
|
||||||
|
case 34: return QByteArray::fromRawData(reinterpret_cast<char*>(ndsHeader->NintendoLogo), 0x9C).toHex();
|
||||||
|
case 35: return QString::number(ndsHeader->NintendoLogoCRC,16);
|
||||||
|
case 36: return QString::number(ndsHeader->HeaderCRC16,16);
|
||||||
|
case 37: return QString::number(ndsHeader->DebugRomAddr,16);
|
||||||
|
case 38: return QString::number(ndsHeader->DebugSize,16);
|
||||||
|
case 39: return QString::number(ndsHeader->DebugRamAddr,16);
|
||||||
|
case 40: return QString::number((ndsHeader->IconTitleAddr+IconTitleSize),16);
|
||||||
|
default: return QString("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NDSHeaderModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if(role != Qt::EditRole)
|
||||||
|
return QAbstractTableModel::setData(index, value, role);
|
||||||
|
|
||||||
|
switch (index.row())
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
std::fill_n(ndsHeader->GameTitle, 0xC, 0x0);
|
||||||
|
QString gameTitleStr = value.toString().toUpper();
|
||||||
|
size_t size = std::min<size_t>(gameTitleStr.size(), 0xC);
|
||||||
|
std::copy_n(qUtf8Printable(gameTitleStr), size, ndsHeader->GameTitle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
std::fill_n(ndsHeader->GameCode, 0x4, 0x0);
|
||||||
|
QString gameCodeStr = value.toString().toUpper();
|
||||||
|
size_t size = std::min<size_t>(gameCodeStr.size(), 0x4);
|
||||||
|
std::copy_n(qUtf8Printable(gameCodeStr), size, ndsHeader->GameCode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
std::fill_n(ndsHeader->MakerCode, 0x2, 0x0);
|
||||||
|
QString makerCodeStr = value.toString().toUpper();
|
||||||
|
size_t size = std::min<size_t>(makerCodeStr.size(), 0x2);
|
||||||
|
std::copy_n(qUtf8Printable(makerCodeStr), size, ndsHeader->MakerCode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: ndsHeader->UnitCode = static_cast<unsigned char>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 4: ndsHeader->DeviceType = static_cast<unsigned char>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 5: ndsHeader->DeviceSize = static_cast<unsigned char>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 6: ndsHeader->RomVersion = static_cast<unsigned char>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 7: ndsHeader->Flags = static_cast<unsigned char>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 8: ndsHeader->Arm9RomAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 9: ndsHeader->Arm9EntryAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 10: ndsHeader->Arm9RamAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 11: ndsHeader->Arm9Size = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 12: ndsHeader->Arm7RomAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 13: ndsHeader->Arm7EntryAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 14: ndsHeader->Arm7RamAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 15: ndsHeader->Arm7Size = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 16: ndsHeader->FilenameTableAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 17: ndsHeader->FilenameSize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 18: ndsHeader->FATAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 19: ndsHeader->FATSize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 20: ndsHeader->Arm9OverlayAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 21: ndsHeader->Arm9OverlaySize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 22: ndsHeader->Arm7OverlayAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 23: ndsHeader->Arm7OverlaySize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 24: ndsHeader->NormalCommandsSettings = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 25: ndsHeader->Key1CommandsSettings = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 26: ndsHeader->IconTitleAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 27: ndsHeader->SecureAreaCRC16 = static_cast<uint16_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 28: ndsHeader->SecureAreaLoadingTimeout = static_cast<uint16_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 29: ndsHeader->ARM9AutoLoadListRamAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 30: ndsHeader->ARM7AutoLoadListRamAddr = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 31: ndsHeader->SecureAreaDisable = static_cast<uint64_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 32: ndsHeader->RomSize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 33: ndsHeader->HeaderSize = static_cast<uint32_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 34:
|
||||||
|
{
|
||||||
|
std::fill_n(ndsHeader->NintendoLogo, 0x9C, 0x0);
|
||||||
|
QByteArray nintendoLogoBytes = QByteArray::fromHex(qUtf8Printable(value.toString()));
|
||||||
|
size_t size = std::min<size_t>(nintendoLogoBytes.size(), 0x9C);
|
||||||
|
std::copy_n(std::begin(nintendoLogoBytes), size, ndsHeader->NintendoLogo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 35: ndsHeader->NintendoLogoCRC = static_cast<uint16_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
case 36: ndsHeader->HeaderCRC16 = static_cast<uint16_t>(value.toString().toUInt(nullptr, 16)); break;
|
||||||
|
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;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
Q_EMIT this->dataChanged(index, index);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant NDSHeaderModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if(orientation == Qt::Horizontal)
|
||||||
|
{
|
||||||
|
if(role == Qt::DisplayRole)
|
||||||
|
{
|
||||||
|
switch(section)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "Name";
|
||||||
|
case 1:
|
||||||
|
return "Value";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags NDSHeaderModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.isValid() && index.column() == 1 && isValueRowEditable)
|
||||||
|
return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
|
||||||
|
|
||||||
|
return QAbstractItemModel::flags(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NDSHeaderModel::setValueRowEditable(bool isEditable)
|
||||||
|
{
|
||||||
|
isValueRowEditable = isEditable;
|
||||||
|
}
|
||||||
22
ui/models/ndsheadermodel.h
Normal file
22
ui/models/ndsheadermodel.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
struct NDSHeader;
|
||||||
|
|
||||||
|
class NDSHeaderModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NDSHeaderModel(NDSHeader *ndsHeader, QObject *parent = nullptr);
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
void setValueRowEditable(bool isEditable);
|
||||||
|
private:
|
||||||
|
NDSHeader *ndsHeader;
|
||||||
|
bool isValueRowEditable = false;
|
||||||
|
};
|
||||||
45
ui/tabs/commons/headernames.cpp
Normal file
45
ui/tabs/commons/headernames.cpp
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include "headernames.h"
|
||||||
|
|
||||||
|
std::vector<std::string> ndsHeaderNamesArr = {
|
||||||
|
"Game Title",
|
||||||
|
"Game Code",
|
||||||
|
"Maker Code",
|
||||||
|
"Unit Code",
|
||||||
|
"Device Code",
|
||||||
|
"Card Size",
|
||||||
|
"Card Info",
|
||||||
|
"Flags",
|
||||||
|
"ARM9 Rom Address",
|
||||||
|
"ARM9 Entry Address",
|
||||||
|
"ARM9 Ram Address",
|
||||||
|
"ARM9 Size",
|
||||||
|
"ARM7 Rom Address",
|
||||||
|
"ARM7 Entry Address",
|
||||||
|
"ARM7 Ram Address",
|
||||||
|
"ARM7 Size",
|
||||||
|
"Filename Table Address",
|
||||||
|
"Filename Table Size",
|
||||||
|
"FAT Address",
|
||||||
|
"FAT Size",
|
||||||
|
"ARM9 Overlay Address",
|
||||||
|
"ARM9 Overlay Size",
|
||||||
|
"ARM7 Overlay Address",
|
||||||
|
"ARM7 Overlay Size",
|
||||||
|
"Port 40001A4h NC",
|
||||||
|
"Port 40001a4h KC",
|
||||||
|
"Icon/Title Address",
|
||||||
|
"Secure Area CRC16",
|
||||||
|
"Secure Area Timeout",
|
||||||
|
"ARM9 AL Ram Address",
|
||||||
|
"ARM7 AL Ram Address",
|
||||||
|
"Secure Area Disable",
|
||||||
|
"Used Rom Size",
|
||||||
|
"Header Size",
|
||||||
|
"Nintendo Logo",
|
||||||
|
"Nintendo Logo CRC",
|
||||||
|
"Header CRC",
|
||||||
|
"Debug Rom Address",
|
||||||
|
"Debug Size",
|
||||||
|
"Debug Ram Address",
|
||||||
|
"FAT Files Address"
|
||||||
|
};
|
||||||
53
ui/tabs/commons/headernames.h
Normal file
53
ui/tabs/commons/headernames.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
extern std::vector<std::string> ndsHeaderNamesArr;
|
||||||
|
|
||||||
|
namespace NDSHeaderNames {
|
||||||
|
enum {
|
||||||
|
GameTitle,
|
||||||
|
GameCode,
|
||||||
|
MakerCode,
|
||||||
|
UnitCode,
|
||||||
|
DeviceCode,
|
||||||
|
CardSize,
|
||||||
|
CardInfo,
|
||||||
|
Flags,
|
||||||
|
ARM9RomAddress,
|
||||||
|
ARM9EntryAddress,
|
||||||
|
ARM9RamAddress,
|
||||||
|
ARM9Size,
|
||||||
|
ARM7RomAddress,
|
||||||
|
ARM7EntryAddress,
|
||||||
|
ARM7RamAddress,
|
||||||
|
ARM7Size,
|
||||||
|
FilenameTableAddress,
|
||||||
|
FilenameTableSize,
|
||||||
|
FATAddress,
|
||||||
|
FATSize,
|
||||||
|
ARM9OverlayAddress,
|
||||||
|
ARM9OverlaySize,
|
||||||
|
ARM7OverlayAddress,
|
||||||
|
ARM7OverlaySize,
|
||||||
|
Port40001A4hNC,
|
||||||
|
Port40001a4hKC,
|
||||||
|
IconTitleAddress,
|
||||||
|
SecureAreaCRC16,
|
||||||
|
SecureAreaTimeout,
|
||||||
|
ARM9ALRamAddress,
|
||||||
|
ARM7ALRamAddress,
|
||||||
|
SecureAreaDisable,
|
||||||
|
UsedRomSize,
|
||||||
|
HeaderSize,
|
||||||
|
NintendoLogo,
|
||||||
|
NintendoLogoCRC,
|
||||||
|
HeaderCRC,
|
||||||
|
DebugRomAddress,
|
||||||
|
DebugSize,
|
||||||
|
DebugRamAddress,
|
||||||
|
FATFilesAddress
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "mainwindow.h"
|
#include "./../../mainwindow.h"
|
||||||
|
|
||||||
|
|
||||||
bool MainWindow::patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath)
|
bool MainWindow::patchFat(const std::string& loadPath, uint32_t shiftSize, const std::string& savePath)
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "mainwindow.h"
|
#include "./../../mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "./../../ui_mainwindow.h"
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_fatPatchingLoadFatBtn_clicked()
|
void MainWindow::on_fatPatcherLoadFatBtn_clicked()
|
||||||
{
|
{
|
||||||
QString fatPath = QFileDialog::getOpenFileName(
|
QString fatPath = QFileDialog::getOpenFileName(
|
||||||
Q_NULLPTR,
|
Q_NULLPTR,
|
||||||
@@ -14,15 +14,15 @@ void MainWindow::on_fatPatchingLoadFatBtn_clicked()
|
|||||||
|
|
||||||
if( !fatPath.isNull() )
|
if( !fatPath.isNull() )
|
||||||
{
|
{
|
||||||
ui->fatPatchingFatPathEdt->setText(fatPath.toUtf8());
|
ui->fatPatcherFatPathEdt->setText(fatPath.toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_fatPatchingPatchFatBtn_clicked()
|
void MainWindow::on_fatPatcherPatchFatBtn_clicked()
|
||||||
{
|
{
|
||||||
uint32_t positionDiff = 0;
|
uint32_t positionDiff = 0;
|
||||||
uint32_t originalPos = ui->fatPatchingOriginalFatFilesAddrEdt->text().toUInt(nullptr, 16);
|
uint32_t originalPos = ui->fatPatcherOriginalFatFilesAddrEdt->text().toUInt(nullptr, 16);
|
||||||
uint32_t newPos = ui->fatPatchingNewFatFilesAddrEdt->text().toUInt(nullptr, 16);
|
uint32_t newPos = ui->fatPatcherNewFatFilesAddrEdt->text().toUInt(nullptr, 16);
|
||||||
|
|
||||||
QString dirPath = QFileDialog::getSaveFileName(
|
QString dirPath = QFileDialog::getSaveFileName(
|
||||||
Q_NULLPTR,
|
Q_NULLPTR,
|
||||||
@@ -42,7 +42,7 @@ void MainWindow::on_fatPatchingPatchFatBtn_clicked()
|
|||||||
positionDiff = originalPos-newPos;
|
positionDiff = originalPos-newPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
patchFat(ui->fatPatchingFatPathEdt->text().toStdString(), positionDiff, dirPath.toStdString())
|
patchFat(ui->fatPatcherFatPathEdt->text().toStdString(), positionDiff, dirPath.toStdString())
|
||||||
? QMessageBox::information(this, tr("NDS Factory"), tr("FAT patching completed!"))
|
? QMessageBox::information(this, tr("NDS Factory"), tr("FAT patching completed!"))
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error patching FAT!"));
|
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error patching FAT!"));
|
||||||
|
|
||||||
351
ui/tabs/packer/packertabfunctions.cpp
Normal file
351
ui/tabs/packer/packertabfunctions.cpp
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
#include <QDir>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "./../../mainwindow.h"
|
||||||
|
#include "./../../ui_mainwindow.h"
|
||||||
|
#include "../commons/headernames.h"
|
||||||
|
#include "../../models/ndsheadermodel.h"
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::populatePackerSectionHeader(NDSHeader *ndsHeader)
|
||||||
|
{
|
||||||
|
auto* headerDataModel = new NDSHeaderModel(ndsHeader);
|
||||||
|
headerDataModel->setValueRowEditable(true);
|
||||||
|
ui->packerHeaderDataTable->setModel(headerDataModel);
|
||||||
|
ui->packerHeaderDataTable->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||||
|
ui->packerHeaderDataTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
|
||||||
|
ui->packerHeaderDataTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::Stretch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::enableCalcCrcButton()
|
||||||
|
{
|
||||||
|
ui->packerCalcHeaderCrcBtn->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::enableBuildRomButton()
|
||||||
|
{
|
||||||
|
ui->packerBuildNDSRomBtn->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::generateHeader(NDSHeader* pRomHeader)
|
||||||
|
{
|
||||||
|
std::copy_n(extractPackerHeaderTableData(NDSHeaderNames::GameTitle).toLatin1().data(), 0xc, std::begin(pRomHeader->GameTitle));
|
||||||
|
|
||||||
|
|
||||||
|
std::copy_n(extractPackerHeaderTableData(NDSHeaderNames::GameCode).toLatin1().data(), 0x4, std::begin(pRomHeader->GameCode));
|
||||||
|
std::copy_n(extractPackerHeaderTableData(NDSHeaderNames::MakerCode).toLatin1().data(), 0x2, std::begin(pRomHeader->MakerCode));
|
||||||
|
pRomHeader->UnitCode = static_cast<unsigned char>(extractPackerHeaderTableData(NDSHeaderNames::UnitCode).toUInt(nullptr, 16));
|
||||||
|
|
||||||
|
pRomHeader->DeviceType = static_cast<unsigned char>(extractPackerHeaderTableData(NDSHeaderNames::DeviceCode).toUInt(nullptr, 16));
|
||||||
|
pRomHeader->DeviceSize = static_cast<unsigned char>(extractPackerHeaderTableData(NDSHeaderNames::CardSize).toUInt(nullptr, 16));
|
||||||
|
|
||||||
|
std::fill(std::begin(pRomHeader->Reserved1), std::end(pRomHeader->Reserved1), 0);
|
||||||
|
|
||||||
|
pRomHeader->RomVersion = static_cast<unsigned char>(extractPackerHeaderTableData(NDSHeaderNames::CardInfo).toUInt(nullptr, 16));
|
||||||
|
pRomHeader->Flags = static_cast<unsigned char>(extractPackerHeaderTableData(NDSHeaderNames::Flags).toUInt(nullptr, 16));
|
||||||
|
|
||||||
|
pRomHeader->Arm9RomAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9RomAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm9EntryAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9EntryAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm9RamAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9RamAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm9Size = extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->Arm7RomAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7RomAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm7EntryAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7EntryAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm7RamAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7RamAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm7Size = extractPackerHeaderTableData(NDSHeaderNames::ARM7Size).toUInt(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->FilenameTableAddr = extractPackerHeaderTableData(NDSHeaderNames::FilenameTableAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->FilenameSize = extractPackerHeaderTableData(NDSHeaderNames::FilenameTableSize).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->FATAddr = extractPackerHeaderTableData(NDSHeaderNames::FATAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->FATSize = extractPackerHeaderTableData(NDSHeaderNames::FATSize).toUInt(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->Arm9OverlayAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm9OverlaySize = extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlaySize).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm7OverlayAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7OverlayAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Arm7OverlaySize = extractPackerHeaderTableData(NDSHeaderNames::ARM7OverlaySize).toUInt(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->NormalCommandsSettings = extractPackerHeaderTableData(NDSHeaderNames::Port40001A4hNC).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->Key1CommandsSettings = extractPackerHeaderTableData(NDSHeaderNames::Port40001a4hKC).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->IconTitleAddr = extractPackerHeaderTableData(NDSHeaderNames::IconTitleAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->SecureAreaCRC16 = extractPackerHeaderTableData(NDSHeaderNames::SecureAreaCRC16).toUShort(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->SecureAreaLoadingTimeout = extractPackerHeaderTableData(NDSHeaderNames::SecureAreaTimeout).toUShort(nullptr, 16);
|
||||||
|
pRomHeader->ARM9AutoLoadListRamAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9ALRamAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->ARM7AutoLoadListRamAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7ALRamAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->SecureAreaDisable = extractPackerHeaderTableData(NDSHeaderNames::SecureAreaDisable).toULong(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->RomSize = extractPackerHeaderTableData(NDSHeaderNames::UsedRomSize).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->HeaderSize = extractPackerHeaderTableData(NDSHeaderNames::HeaderSize).toUInt(nullptr, 16);
|
||||||
|
|
||||||
|
std::fill(std::begin(pRomHeader->Reserved2), std::end(pRomHeader->Reserved2), 0);
|
||||||
|
std::copy_n(std::begin(QByteArray::fromHex(extractPackerHeaderTableData(NDSHeaderNames::NintendoLogo).toUtf8())), 0x9C, std::begin(pRomHeader->NintendoLogo));
|
||||||
|
pRomHeader->NintendoLogoCRC = extractPackerHeaderTableData(NDSHeaderNames::NintendoLogoCRC).toUShort(nullptr, 16);
|
||||||
|
|
||||||
|
pRomHeader->HeaderCRC16 = extractPackerHeaderTableData(NDSHeaderNames::HeaderCRC).toUShort(nullptr, 16);
|
||||||
|
pRomHeader->DebugRomAddr = extractPackerHeaderTableData(NDSHeaderNames::DebugRomAddress).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->DebugSize = extractPackerHeaderTableData(NDSHeaderNames::DebugSize).toUInt(nullptr, 16);
|
||||||
|
pRomHeader->DebugRamAddr = extractPackerHeaderTableData(NDSHeaderNames::DebugRamAddress).toUInt(nullptr, 16);
|
||||||
|
|
||||||
|
std::fill(std::begin(pRomHeader->Reserved3), std::end(pRomHeader->Reserved3), 0);
|
||||||
|
std::fill(std::begin(pRomHeader->Reserved4), std::end(pRomHeader->Reserved4), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool 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));;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::calcHeaderCrc16()
|
||||||
|
{
|
||||||
|
std::vector<char> romHeaderBuffer(sizeof(NDSHeader));
|
||||||
|
NDSHeader* pRomHeader = reinterpret_cast<NDSHeader*>(romHeaderBuffer.data());
|
||||||
|
|
||||||
|
generateHeader(pRomHeader);
|
||||||
|
|
||||||
|
QModelIndex headerCrcIndex = ui->packerHeaderDataTable->model()->index(NDSHeaderNames::HeaderCRC, 1);
|
||||||
|
ui->packerHeaderDataTable->model()->setData(headerCrcIndex, QString::number(ndsFactory.calcHeaderCrc16(romHeaderBuffer), 16), Qt::EditRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm9Bin(const std::string& savePath, bool isArm9FooterPresent)
|
||||||
|
{
|
||||||
|
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16);
|
||||||
|
if (isArm9FooterPresent)
|
||||||
|
size += Arm9FooterSize;
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedArm9BinPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9RomAddress).toUInt(nullptr, 16),
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm7Bin(const std::string& savePath)
|
||||||
|
{
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedArm7BinPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM7RomAddress).toUInt(nullptr, 16),
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM7Size).toUInt(nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeFnt(const std::string& savePath)
|
||||||
|
{
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedFntPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::FilenameTableAddress).toUInt(nullptr, 16),
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::FilenameTableSize).toUInt(nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeFat(const std::string& savePath)
|
||||||
|
{
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedFatPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::FATAddress).toUInt(nullptr, 16),
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::FATSize).toUInt(nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm9Overlay(const std::string& savePath)
|
||||||
|
{
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedArm9OverlayPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16),
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlaySize).toUInt(nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm9OverlayFiles([[maybe_unused]] const std::string& savePath)
|
||||||
|
{
|
||||||
|
return false; // TODO: implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm7Overlay(const std::string& savePath)
|
||||||
|
{
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedArm7OverlayPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16),
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlaySize).toUInt(nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm7OverlayFiles([[maybe_unused]] const std::string& savePath)
|
||||||
|
{
|
||||||
|
return false; // TODO: implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeIconTitle(const std::string& savePath)
|
||||||
|
{
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedIconTitlePathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::IconTitleAddress).toUInt(nullptr, 16),
|
||||||
|
IconTitleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool 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;
|
||||||
|
|
||||||
|
return ndsFactory.writeSectionToFile(
|
||||||
|
ui->loadedFatFilesPathEdt->text().toStdString(),
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeHeaderPadding(char paddingType, const std::string& savePath)
|
||||||
|
{
|
||||||
|
uint32_t startAddr = sizeof(NDSHeader);
|
||||||
|
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::ARM9RomAddress).toUInt(nullptr, 16) - startAddr;
|
||||||
|
|
||||||
|
return ndsFactory.writePaddingToFile(
|
||||||
|
paddingType,
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm9BinPadding(char paddingType, const std::string& savePath, bool isFooterPresent)
|
||||||
|
{ // FIXME check ARM9 Overlay
|
||||||
|
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM9RomAddress).toUInt(nullptr, 16) +
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16);
|
||||||
|
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::ARM7RomAddress).toUInt(nullptr, 16) - startAddr;
|
||||||
|
|
||||||
|
if (isFooterPresent)
|
||||||
|
size -= Arm9FooterSize;
|
||||||
|
|
||||||
|
return ndsFactory.writePaddingToFile(
|
||||||
|
paddingType,
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm7BinPadding(char paddingType, const std::string& savePath)
|
||||||
|
{ // FIXME check ARM7 Overlay
|
||||||
|
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::ARM7RomAddress).toUInt(nullptr, 16) +
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM7Size).toUInt(nullptr, 16);
|
||||||
|
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::FilenameTableAddress).toUInt(nullptr, 16) - startAddr;
|
||||||
|
|
||||||
|
return ndsFactory.writePaddingToFile(
|
||||||
|
paddingType,
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeFntPadding(char paddingType, const std::string& savePath)
|
||||||
|
{
|
||||||
|
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::FilenameTableAddress).toUInt(nullptr, 16) +
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::FilenameTableSize).toUInt(nullptr, 16);
|
||||||
|
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::FATAddress).toUInt(nullptr, 16) - startAddr;
|
||||||
|
|
||||||
|
return ndsFactory.writePaddingToFile(
|
||||||
|
paddingType,
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeFatPadding(char paddingType, const std::string& savePath)
|
||||||
|
{
|
||||||
|
uint32_t startAddr = extractPackerHeaderTableData(NDSHeaderNames::FATAddress).toUInt(nullptr, 16) +
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::FATSize).toUInt(nullptr, 16);
|
||||||
|
uint32_t size = extractPackerHeaderTableData(NDSHeaderNames::IconTitleAddress).toUInt(nullptr, 16) - startAddr;
|
||||||
|
|
||||||
|
return ndsFactory.writePaddingToFile(
|
||||||
|
paddingType,
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm9OverlayPadding([[maybe_unused]] char paddingType, [[maybe_unused]] const std::string& savePath)
|
||||||
|
{ // FIXME TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm9OverlayFilesPadding([[maybe_unused]] char paddingType, [[maybe_unused]] const std::string& savePath)
|
||||||
|
{ // FIXME TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeArm7OverlayPadding([[maybe_unused]] char paddingType, [[maybe_unused]] const std::string& savePath)
|
||||||
|
{ // FIXME TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MainWindow::writeArm7OverlayFilesPadding([[maybe_unused]] char paddingType, [[maybe_unused]] const std::string& savePath)
|
||||||
|
{ // FIXME TODO
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool 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;
|
||||||
|
|
||||||
|
return ndsFactory.writePaddingToFile(
|
||||||
|
static_cast<char>('\xff'),
|
||||||
|
savePath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::writeEverything(const std::string& savePath)
|
||||||
|
{
|
||||||
|
bool res = true;
|
||||||
|
char paddingType;
|
||||||
|
bool isArm9FooterPresent = ndsFactory.checkArm9FooterPresence(ui->loadedArm9BinPathEdt->text().toStdString(),
|
||||||
|
extractPackerHeaderTableData(NDSHeaderNames::ARM9Size).toUInt(nullptr, 16));
|
||||||
|
if (ui->packerPadType00RdBtn->isChecked())
|
||||||
|
paddingType = static_cast<char>('\x00');
|
||||||
|
else
|
||||||
|
paddingType = static_cast<char>('\xff');
|
||||||
|
|
||||||
|
std::remove(savePath.c_str());
|
||||||
|
|
||||||
|
res &= writeHeader(savePath);
|
||||||
|
res &= writeHeaderPadding(paddingType, savePath);
|
||||||
|
res &= writeArm9Bin(savePath, isArm9FooterPresent);
|
||||||
|
res &= writeArm9BinPadding(paddingType, savePath, isArm9FooterPresent);
|
||||||
|
res &= writeArm7Bin(savePath);
|
||||||
|
res &= writeArm7BinPadding(paddingType, savePath);
|
||||||
|
res &= writeFnt(savePath);
|
||||||
|
res &= writeFntPadding(paddingType, savePath);
|
||||||
|
res &= writeFat(savePath);
|
||||||
|
res &= writeFatPadding(paddingType, savePath);
|
||||||
|
if(extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16) != 0) {
|
||||||
|
res &= writeArm9Overlay(savePath);
|
||||||
|
res &= writeArm9OverlayPadding(paddingType, savePath);
|
||||||
|
res &= writeArm9OverlayFiles(savePath);
|
||||||
|
res &= writeArm9OverlayFilesPadding(paddingType, savePath);
|
||||||
|
}
|
||||||
|
if(extractPackerHeaderTableData(NDSHeaderNames::ARM9OverlayAddress).toUInt(nullptr, 16) != 0) {
|
||||||
|
res &= writeArm7Overlay(savePath);
|
||||||
|
res &= writeArm7OverlayPadding(paddingType, savePath);
|
||||||
|
res &= writeArm7OverlayFiles(savePath);
|
||||||
|
res &= writeArm7OverlayFilesPadding(paddingType, savePath);
|
||||||
|
}
|
||||||
|
res &= writeIconTitle(savePath);
|
||||||
|
res &= writeFatFiles(savePath);
|
||||||
|
if(!ui->packerTrimRomsCbx->isChecked())
|
||||||
|
{
|
||||||
|
res &= writeRomPadding(savePath);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString MainWindow::extractPackerHeaderTableData(int index)
|
||||||
|
{
|
||||||
|
return ui->packerHeaderDataTable->model()->index(index, 1).data().toString();
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "mainwindow.h"
|
#include "./../../mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "./../../ui_mainwindow.h"
|
||||||
|
#include "../commons/headernames.h"
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_packerLoadHeaderBtn_clicked()
|
void MainWindow::on_packerLoadHeaderBtn_clicked()
|
||||||
{
|
{
|
||||||
std::vector<char> romHeader;
|
|
||||||
NDSHeader *pNDSHeader;
|
NDSHeader *pNDSHeader;
|
||||||
|
|
||||||
QString headerPath = QFileDialog::getOpenFileName(
|
QString headerPath = QFileDialog::getOpenFileName(
|
||||||
@@ -24,6 +25,8 @@ void MainWindow::on_packerLoadHeaderBtn_clicked()
|
|||||||
{
|
{
|
||||||
pNDSHeader = reinterpret_cast<NDSHeader*>(romHeader.data());
|
pNDSHeader = reinterpret_cast<NDSHeader*>(romHeader.data());
|
||||||
populatePackerSectionHeader(pNDSHeader);
|
populatePackerSectionHeader(pNDSHeader);
|
||||||
|
enableCalcCrcButton();
|
||||||
|
enableBuildRomButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +167,6 @@ void MainWindow::on_packerLoadFatFilesBtn_clicked()
|
|||||||
if(!fatFilesPath.isNull())
|
if(!fatFilesPath.isNull())
|
||||||
{
|
{
|
||||||
ui->loadedFatFilesPathEdt->setText(fatFilesPath.toUtf8());
|
ui->loadedFatFilesPathEdt->setText(fatFilesPath.toUtf8());
|
||||||
ui->packerFatFilesAddrEdt->setText(QString::number((ui->packerIconTitleEdt->text().toUInt(nullptr, 16) + IconTitleSize), 16));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,3 +185,7 @@ void MainWindow::on_packerBuildNDSRomBtn_clicked()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_packerCalcHeaderCrcBtn_clicked()
|
||||||
|
{
|
||||||
|
calcHeaderCrc16();
|
||||||
|
}
|
||||||
318
ui/tabs/unpacker/unpackertabfunctions.cpp
Normal file
318
ui/tabs/unpacker/unpackertabfunctions.cpp
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
#include <QDir>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include "../../mainwindow.h"
|
||||||
|
#include "../../ui_mainwindow.h"
|
||||||
|
#include "../commons/headernames.h"
|
||||||
|
#include "../../models/ndsheadermodel.h"
|
||||||
|
#include "../../../ndsfactory/fatstruct.h"
|
||||||
|
|
||||||
|
// Byte offsets for interpreting memory
|
||||||
|
#define SECOND_BYTE_SHIFT 8
|
||||||
|
#define THIRD_BYTE_SHIFT 16
|
||||||
|
#define FOURTH_BYTE_SHIFT 24
|
||||||
|
|
||||||
|
// Magic values for FAT extraction
|
||||||
|
#define CONTROL_BYTE_LENGTH_MASK 0x7F
|
||||||
|
#define CONTROL_BYTE_DIR_MASK 0x80
|
||||||
|
#define DUMMY_CONTROL_VALUE 0xFF
|
||||||
|
#define FNT_HEADER_OFFSET_MASK 0XFFF
|
||||||
|
#define ROOT_DIRECTORY_ADDRESS 0xF000
|
||||||
|
|
||||||
|
// Size constants
|
||||||
|
#define ICON_TITLE_SIZE 0xA00
|
||||||
|
|
||||||
|
void MainWindow::populateHeader(NDSHeader* ndsHeader)
|
||||||
|
{
|
||||||
|
auto* headerDataModel = new NDSHeaderModel(ndsHeader);
|
||||||
|
ui->unpackerHeaderDataTable->setModel(headerDataModel);
|
||||||
|
ui->unpackerHeaderDataTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeMode::ResizeToContents);
|
||||||
|
ui->unpackerHeaderDataTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::Stretch);
|
||||||
|
}
|
||||||
|
|
||||||
|
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){
|
||||||
|
ui->unpackerDumpArm9OverlayBtn->setEnabled(false);
|
||||||
|
ui->unpackerDumpArm9OverlayFilesBtn->setEnabled(false);
|
||||||
|
}
|
||||||
|
if (ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlayAddress, 1).data().toString().toUInt(nullptr,16) == 0){
|
||||||
|
ui->unpackerDumpArm7OverlayBtn->setEnabled(false);
|
||||||
|
ui->unpackerDumpArm7OverlayFilesBtn->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::disableExtractionButtons()
|
||||||
|
{
|
||||||
|
ui->unpackerExtractorGbx->setEnabled(false);
|
||||||
|
ui->unpackerExtraGbx->setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpHeader(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
0,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::HeaderSize, 1).data().toString().toUInt(nullptr,16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool 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)
|
||||||
|
size += 12;
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9RomAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpArm7Bin(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7RomAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7Size, 1).data().toString().toUInt(nullptr,16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpFnt(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FilenameTableAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FilenameTableSize, 1).data().toString().toUInt(nullptr,16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpFat(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FATAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FATSize, 1).data().toString().toUInt(nullptr,16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpArm9Overlay(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlayAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM9OverlaySize, 1).data().toString().toUInt(nullptr,16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpArm9OverlayFiles([[maybe_unused]] const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return false; // TODO: implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpArm7Overlay(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlayAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::ARM7OverlaySize, 1).data().toString().toUInt(nullptr,16));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpArm7OverlayFiles([[maybe_unused]] const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return false; // TODO: implement me!
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::dumpIconTitle(const std::string& dirPath)
|
||||||
|
{
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::IconTitleAddress, 1).data().toString().toUInt(nullptr,16),
|
||||||
|
ICON_TITLE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool 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;
|
||||||
|
|
||||||
|
return ndsFactory.dumpDataFromFile(
|
||||||
|
ui->loadedRomPath->text().toStdString(),
|
||||||
|
dirPath,
|
||||||
|
startAddr,
|
||||||
|
size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool 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());
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MainWindow::decodeFatFiles(QString dirPath)
|
||||||
|
{
|
||||||
|
// Prepare necessary info from ROM
|
||||||
|
|
||||||
|
std::string romPath = ui->loadedRomPath->text().toStdString(); // ROM itself
|
||||||
|
|
||||||
|
// Addresses of the file allocation table and file name table
|
||||||
|
|
||||||
|
uint32_t fatAddr = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FATAddress, 1).data().toString().toUInt(nullptr,16);
|
||||||
|
uint32_t fatSize = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FATSize, 1).data().toString().toUInt(nullptr,16);
|
||||||
|
|
||||||
|
// Sizes of these tables
|
||||||
|
|
||||||
|
uint32_t fntAddr = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FilenameTableAddress, 1).data().toString().toUInt(nullptr,16);
|
||||||
|
uint32_t fntSize = ui->unpackerHeaderDataTable->model()->index(NDSHeaderNames::FilenameTableSize, 1).data().toString().toUInt(nullptr,16);
|
||||||
|
|
||||||
|
// Buffers to receive the contents of the FAT and FNT
|
||||||
|
|
||||||
|
std::vector<char> fatBytes(static_cast<unsigned long>(fatSize));
|
||||||
|
std::vector<char> fntBytes(static_cast<unsigned long>(fntSize));
|
||||||
|
|
||||||
|
// Fill them
|
||||||
|
|
||||||
|
if(!ndsFactory.readBytesFromFile(fatBytes, romPath, fatAddr, fatSize)) return false;
|
||||||
|
if(!ndsFactory.readBytesFromFile(fntBytes, romPath, fntAddr, fntSize)) return false;
|
||||||
|
|
||||||
|
// Use the available FAT range struct and read the FAT bytes as such
|
||||||
|
|
||||||
|
FatRange* pfatrange = reinterpret_cast<FatRange*>(fatBytes.data());
|
||||||
|
|
||||||
|
// Recursive function that looks up FNT info to find file names and directory structures,
|
||||||
|
// And writes the ROM data in the ranges indicated by the FAT simultaneously.
|
||||||
|
|
||||||
|
auto parseFolder = [this, fntBytes, pfatrange, romPath](uint32_t folderId, std::string curPath, auto& parseFolder){
|
||||||
|
|
||||||
|
if(false) return false; // this is stupid, but it's C++
|
||||||
|
// If we take it out, the compiler will complain because it doesn't known the return type of the lambda
|
||||||
|
// But we can't make the lambda bool either...so this is the best option...
|
||||||
|
|
||||||
|
QDir curDir(QString::fromStdString(curPath)); // useful a bit later
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// About how the FAT and FNT work :
|
||||||
|
|
||||||
|
// The FNT has two sections :
|
||||||
|
// a "header" where every entry contains :
|
||||||
|
// - a 4-byte address where the corresponding directory's data starts in the body
|
||||||
|
// - a 2-byte offset that is the index of the first file of the directory in the FAT
|
||||||
|
// (e.g. : if the offset is 42, the first file in the directory is situated at the ROM addresses stored in the 42nd FAT entry)
|
||||||
|
// (and its second will be 43, etc.)
|
||||||
|
// a "body" where every entry contains :
|
||||||
|
// - a length+status/control byte : lower 7 bits (control byte & 0x7F) are a length, highest bit (control byte & 0x80) is set if entry is a directory, and not set if it's a file
|
||||||
|
// - a name which length is the length portion of the previous control byte (e.g. : if the control byte was 0x83, the name is three bytes long)
|
||||||
|
// - if the entry is a directory, a 2-byte address (where only the lower 12 bit are relevant for some reason) at which this directory's info is located in the FNT header
|
||||||
|
|
||||||
|
// Thus, the FNT reading operation will consist in bouncing back and forth between body and header every time we must process a subdirectory
|
||||||
|
// Thank Heavens for random-access containers !
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Get the 4-byte address for the folder data
|
||||||
|
|
||||||
|
uint32_t fntBodyOffset =
|
||||||
|
(uint32_t)((unsigned char) fntBytes[currentOffset+3] << (uint32_t) FOURTH_BYTE_SHIFT |
|
||||||
|
(unsigned char) fntBytes[currentOffset+2] << (uint32_t) THIRD_BYTE_SHIFT |
|
||||||
|
(unsigned char) fntBytes[currentOffset + 1] << (uint32_t) SECOND_BYTE_SHIFT |
|
||||||
|
(unsigned char) fntBytes[currentOffset]);
|
||||||
|
currentOffset+=4;
|
||||||
|
|
||||||
|
// Get the 2-byte offset for the folder's first file in the FAT
|
||||||
|
|
||||||
|
uint16_t fatOffset =
|
||||||
|
(uint16_t)((unsigned char) fntBytes[currentOffset+1] << SECOND_BYTE_SHIFT |
|
||||||
|
(unsigned char) fntBytes[currentOffset]);
|
||||||
|
|
||||||
|
// Jump to FNT body a specified address
|
||||||
|
|
||||||
|
currentOffset = fntBodyOffset;
|
||||||
|
|
||||||
|
uint8_t controlByte = DUMMY_CONTROL_VALUE;
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
|
||||||
|
controlByte = fntBytes[currentOffset]; // Entry's control byte
|
||||||
|
if(controlByte==0) break; // A control byte of 0 terminates the directory's contents
|
||||||
|
currentOffset++;
|
||||||
|
|
||||||
|
uint8_t nameLength = controlByte & CONTROL_BYTE_LENGTH_MASK; // length of entry name
|
||||||
|
bool isDir = controlByte & CONTROL_BYTE_DIR_MASK; // set if entry is a directory
|
||||||
|
|
||||||
|
// Reconstitute name from bytes
|
||||||
|
// Btw I wish I could use the actual byte type but I have to comply with the software's choice of using char
|
||||||
|
|
||||||
|
std::vector<char> nameString;
|
||||||
|
for(size_t i = 0 ; i<nameLength ; i++) nameString.push_back(fntBytes[currentOffset++]);
|
||||||
|
std::string name(&nameString[0], (size_t)nameLength);
|
||||||
|
|
||||||
|
// We'll need this either way
|
||||||
|
|
||||||
|
QString newPath(QDir::toNativeSeparators(QString::fromStdString(curPath+"/"+name)));
|
||||||
|
|
||||||
|
if(isDir){
|
||||||
|
|
||||||
|
// Get the 2-byte address for this folder's info in the FNT header
|
||||||
|
uint16_t subFolderId = ((unsigned char) fntBytes[currentOffset+1] << SECOND_BYTE_SHIFT |
|
||||||
|
(unsigned char) fntBytes[currentOffset]);
|
||||||
|
currentOffset+=2;
|
||||||
|
|
||||||
|
// Now the QDir we created earlier comes into play :
|
||||||
|
// C++ doesn't automatically create directories (!!!) so we have to rely on QT to do that manually.
|
||||||
|
// Otherwise, the ofstream will not open,
|
||||||
|
// And even if we force it open, it will just write into nothingness !!!
|
||||||
|
|
||||||
|
if(!curDir.exists(newPath)) curDir.mkdir(newPath); // I don't think the check is even necessary, actually
|
||||||
|
|
||||||
|
// Jump back to the FNT header and repeat the process for subdirectory !
|
||||||
|
|
||||||
|
if(!parseFolder(subFolderId,newPath.toStdString(),parseFolder)) return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
|
||||||
|
// Remember we have the offset for the directory's first file in the FAT.
|
||||||
|
// From then, every file is just the next entry.
|
||||||
|
// So we just have to use that offset and increment it every time.
|
||||||
|
|
||||||
|
if(!ndsFactory.writeFatSectionToFile(
|
||||||
|
romPath,
|
||||||
|
pfatrange+fatOffset,
|
||||||
|
newPath.toStdString()))
|
||||||
|
return false;
|
||||||
|
fatOffset++;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The root folder's ID is, obviously, 0 (only the lower 12-bit count!)
|
||||||
|
|
||||||
|
return parseFolder(ROOT_DIRECTORY_ADDRESS,dirPath.toStdString(),parseFolder);
|
||||||
|
}
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "mainwindow.h"
|
#include "./../../mainwindow.h"
|
||||||
#include "ui_mainwindow.h"
|
#include "./../../ui_mainwindow.h"
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::on_loadRomBtn_clicked()
|
void MainWindow::on_loadRomBtn_clicked()
|
||||||
{
|
{
|
||||||
std::vector<char> romHeader;
|
|
||||||
NDSHeader *pNDSHeader;
|
NDSHeader *pNDSHeader;
|
||||||
|
|
||||||
QString romPath = QFileDialog::getOpenFileName(
|
QString romPath = QFileDialog::getOpenFileName(
|
||||||
@@ -42,10 +41,7 @@ void MainWindow::on_unpackerDumpHeaderBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpHeader(dirPath.toStdString()));
|
||||||
dumpHeader(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpArm9Btn_clicked()
|
void MainWindow::on_unpackerDumpArm9Btn_clicked()
|
||||||
@@ -63,11 +59,7 @@ void MainWindow::on_unpackerDumpArm9Btn_clicked()
|
|||||||
QMessageBox::Yes|QMessageBox::No);
|
QMessageBox::Yes|QMessageBox::No);
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpArm9Bin(dirPath.toStdString(), dumpExtraBytes == QMessageBox::Yes ? true : false));
|
||||||
dumpArm9Bin(dirPath.toStdString(), dumpExtraBytes == QMessageBox::Yes ? true : false)
|
|
||||||
? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpArm7Btn_clicked()
|
void MainWindow::on_unpackerDumpArm7Btn_clicked()
|
||||||
@@ -79,10 +71,7 @@ void MainWindow::on_unpackerDumpArm7Btn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpArm7Bin(dirPath.toStdString()));
|
||||||
dumpArm7Bin(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpFntBtn_clicked()
|
void MainWindow::on_unpackerDumpFntBtn_clicked()
|
||||||
@@ -94,10 +83,7 @@ void MainWindow::on_unpackerDumpFntBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpFnt(dirPath.toStdString()));
|
||||||
dumpFnt(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpFatBtn_clicked()
|
void MainWindow::on_unpackerDumpFatBtn_clicked()
|
||||||
@@ -109,10 +95,7 @@ void MainWindow::on_unpackerDumpFatBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpFat(dirPath.toStdString()));
|
||||||
dumpFat(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpArm9OverlayBtn_clicked()
|
void MainWindow::on_unpackerDumpArm9OverlayBtn_clicked()
|
||||||
@@ -124,10 +107,7 @@ void MainWindow::on_unpackerDumpArm9OverlayBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpArm9Overlay(dirPath.toStdString()));
|
||||||
dumpArm9Overlay(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpArm7OverlayBtn_clicked()
|
void MainWindow::on_unpackerDumpArm7OverlayBtn_clicked()
|
||||||
@@ -139,10 +119,7 @@ void MainWindow::on_unpackerDumpArm7OverlayBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpArm7Overlay(dirPath.toStdString()));
|
||||||
dumpArm7Overlay(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpIconTitleLogoBtn_clicked()
|
void MainWindow::on_unpackerDumpIconTitleLogoBtn_clicked()
|
||||||
@@ -154,10 +131,7 @@ void MainWindow::on_unpackerDumpIconTitleLogoBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpIconTitle(dirPath.toStdString()));
|
||||||
dumpIconTitle(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpFatFilesBtn_clicked()
|
void MainWindow::on_unpackerDumpFatFilesBtn_clicked()
|
||||||
@@ -169,10 +143,7 @@ void MainWindow::on_unpackerDumpFatFilesBtn_clicked()
|
|||||||
"Binary (*.bin)");
|
"Binary (*.bin)");
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpFatFiles(dirPath.toStdString()));
|
||||||
dumpFatFiles(dirPath.toStdString()) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDumpArm9OverlayFilesBtn_clicked()
|
void MainWindow::on_unpackerDumpArm9OverlayFilesBtn_clicked()
|
||||||
@@ -195,15 +166,28 @@ void MainWindow::on_unpackerDumpEverythingBtn_clicked()
|
|||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
|
|
||||||
if (!dirPath.isNull())
|
if (!dirPath.isNull())
|
||||||
{
|
notifyExtractionResult(dumpEverything(dirPath));
|
||||||
dumpEverything(dirPath) ? QMessageBox::information(this, tr("NDS Factory"), tr("Extraction completed!"))
|
|
||||||
: QMessageBox::critical(this, tr("NDS Factory"), tr("Error during the extraction!"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_unpackerDecodeFatFilesBtn_clicked()
|
void MainWindow::on_unpackerDecodeFatFilesBtn_clicked()
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, tr("NDS Factory"), tr("This function is currently not implemented!"));
|
QString dirPath = QFileDialog::getExistingDirectory(
|
||||||
decodeFatFiles();
|
this, tr("Select Directory"),
|
||||||
|
"",
|
||||||
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
|
|
||||||
|
if (!dirPath.isNull())
|
||||||
|
notifyExtractionResult(decodeFatFiles(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!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
60
ui/utils/theme.h
Normal file
60
ui/utils/theme.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QPalette>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
inline void setDarkTheme(QApplication& app)
|
||||||
|
{
|
||||||
|
QPalette darkPalette;
|
||||||
|
darkPalette.setColor(QPalette::Window, QColor(53, 53, 53));
|
||||||
|
darkPalette.setColor(QPalette::WindowText, Qt::white);
|
||||||
|
darkPalette.setColor(QPalette::Base, QColor(35, 35, 35));
|
||||||
|
darkPalette.setColor(QPalette::AlternateBase, QColor(53, 53, 53));
|
||||||
|
darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
|
||||||
|
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||||
|
darkPalette.setColor(QPalette::Text, Qt::white);
|
||||||
|
darkPalette.setColor(QPalette::Button, QColor(53, 53, 53));
|
||||||
|
darkPalette.setColor(QPalette::ButtonText, Qt::white);
|
||||||
|
darkPalette.setColor(QPalette::BrightText, Qt::red);
|
||||||
|
darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||||
|
darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||||
|
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
|
||||||
|
|
||||||
|
app.setPalette(darkPalette);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setLightTheme(QApplication& app)
|
||||||
|
{
|
||||||
|
QPalette lightPalette;
|
||||||
|
lightPalette.setColor(QPalette::Window, QColor(240, 240, 240));
|
||||||
|
lightPalette.setColor(QPalette::WindowText, Qt::black);
|
||||||
|
lightPalette.setColor(QPalette::Base, QColor(255, 255, 255));
|
||||||
|
lightPalette.setColor(QPalette::AlternateBase, QColor(233, 233, 233));
|
||||||
|
lightPalette.setColor(QPalette::ToolTipBase, Qt::black);
|
||||||
|
lightPalette.setColor(QPalette::ToolTipText, Qt::white);
|
||||||
|
lightPalette.setColor(QPalette::Text, Qt::black);
|
||||||
|
lightPalette.setColor(QPalette::Button, QColor(240, 240, 240));
|
||||||
|
lightPalette.setColor(QPalette::ButtonText, Qt::black);
|
||||||
|
lightPalette.setColor(QPalette::BrightText, Qt::red);
|
||||||
|
lightPalette.setColor(QPalette::Link, QColor(42, 130, 218));
|
||||||
|
lightPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
|
||||||
|
lightPalette.setColor(QPalette::HighlightedText, Qt::white);
|
||||||
|
|
||||||
|
app.setPalette(lightPalette);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTheme(QString themeValue)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue("theme", themeValue);
|
||||||
|
QMessageBox::information(nullptr, "NDS Factory", "Restart NDSFactory to change theme!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString getCurrentTheme()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
return settings.value("theme", "default").toString();
|
||||||
|
}
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
#include <QDir>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
|
|
||||||
#include "mainwindow.h"
|
|
||||||
#include "ui_mainwindow.h"
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::populateHeader(NDSHeader* ndsHeader)
|
|
||||||
{
|
|
||||||
|
|
||||||
ui->unpackerGameTitleEdt->setText(QString::fromUtf8(ndsHeader->GameTitle, 0xC));
|
|
||||||
ui->unpackerGameCodeEdt->setText(QString::fromUtf8(ndsHeader->GameCode, 0x4));
|
|
||||||
ui->unpackerMakerCodeEdt->setText(QString::fromUtf8(reinterpret_cast<char*>(ndsHeader->MakerCode), 0x2));
|
|
||||||
ui->unpackerUnitCodeEdt->setText(QString::number(ndsHeader->UnitCode, 16));
|
|
||||||
|
|
||||||
ui->unpackerDeviceCodeEdt->setText(QString::number(ndsHeader->DeviceType, 16));
|
|
||||||
ui->unpackerCardSizeEdt->setText(QString::number(ndsHeader->DeviceSize, 16));
|
|
||||||
ui->unpackerCardInfoEdt->setText(QString::number(ndsHeader->RomVersion, 16));
|
|
||||||
ui->unpackerFlagsEdt->setText(QString::number(ndsHeader->Flags, 16));
|
|
||||||
|
|
||||||
ui->unpackerARM9RomAddrEdt->setText(QString::number(ndsHeader->Arm9RomAddr,16));
|
|
||||||
ui->unpackerARM9EntryAddrEdt->setText(QString::number(ndsHeader->Arm9EntryAddr,16));
|
|
||||||
ui->unpackerARM9RamAddrEdt->setText(QString::number(ndsHeader->Arm9RamAddr,16));
|
|
||||||
ui->unpackerARM9SizeEdt->setText(QString::number(ndsHeader->Arm9Size,16));
|
|
||||||
|
|
||||||
ui->unpackerARM7RomAddrEdt->setText(QString::number(ndsHeader->Arm7RomAddr,16));
|
|
||||||
ui->unpackerARM7EntryAddrEdt->setText(QString::number(ndsHeader->Arm7EntryAddr,16));
|
|
||||||
ui->unpackerARM7RamAddrEdt->setText(QString::number(ndsHeader->Arm7RamAddr,16));
|
|
||||||
ui->unpackerARM7SizeEdt->setText(QString::number(ndsHeader->Arm7Size,16));
|
|
||||||
|
|
||||||
ui->unpackerFilenameTableAddrEdt->setText(QString::number(ndsHeader->FilenameTableAddr,16));
|
|
||||||
ui->unpackerFilenameTableSizeEdt->setText(QString::number(ndsHeader->FilenameSize,16));
|
|
||||||
ui->unpackerFATAddrEdt->setText(QString::number(ndsHeader->FATAddr,16));
|
|
||||||
ui->unpackerFATSizeEdt->setText(QString::number(ndsHeader->FATSize,16));
|
|
||||||
|
|
||||||
ui->unpackerARM9OverlayAddrEdt->setText(QString::number(ndsHeader->Arm9OverlayAddr,16));
|
|
||||||
ui->unpackerARM9OverlaySizeEdt->setText(QString::number(ndsHeader->Arm9OverlaySize,16));
|
|
||||||
ui->unpackerARM7OverlayAddrEdt->setText(QString::number(ndsHeader->Arm7OverlayAddr,16));
|
|
||||||
ui->unpackerARM7OverlaySizeEdt->setText(QString::number(ndsHeader->Arm7OverlaySize,16));
|
|
||||||
|
|
||||||
ui->unpackerPortNCEdt->setText(QString::number(ndsHeader->NormalCommandsSettings,16));
|
|
||||||
ui->unpackerPortKCEdt->setText(QString::number(ndsHeader->Key1CommandsSettings,16));
|
|
||||||
ui->unpackerIconTitleEdt->setText(QString::number(ndsHeader->IconTitleAddr,16));
|
|
||||||
ui->unpackerSecureAreaCRC16Edt->setText(QString::number(ndsHeader->SecureAreaCRC16,16));
|
|
||||||
|
|
||||||
ui->unpackerSecureAreaTimeoutEdt->setText(QString::number(ndsHeader->SecureAreaLoadingTimeout,16));
|
|
||||||
ui->unpackerARM9AURamAddrEdt->setText(QString::number(ndsHeader->ARM9AutoLoadListRamAddr,16));
|
|
||||||
ui->unpackerARM7AURamAddrEdt->setText(QString::number(ndsHeader->ARM7AutoLoadListRamAddr,16));
|
|
||||||
ui->unpackerSecureAreaDisableEdt->setText(QString::number(ndsHeader->SecureAreaDisable,16));
|
|
||||||
|
|
||||||
ui->unpackerUsedRomSizeEdt->setText(QString::number(ndsHeader->RomSize,16));
|
|
||||||
ui->unpackerHeaderSizeEdt->setText(QString::number(ndsHeader->HeaderSize,16));
|
|
||||||
|
|
||||||
ui->unpackerNintendoLogoEdt->setText(QByteArray::fromRawData(reinterpret_cast<char*>(ndsHeader->NintendoLogo), 0x9C).toHex());
|
|
||||||
ui->unpackerNintendoLogoCRCEdt->setText(QString::number(ndsHeader->NintendoLogoCRC,16));
|
|
||||||
|
|
||||||
ui->unpackerHeaderCRCEdt->setText(QString::number(ndsHeader->HeaderCRC16,16));
|
|
||||||
ui->unpackerDebugRomAddrEdt->setText(QString::number(ndsHeader->DebugRomAddr,16));
|
|
||||||
ui->unpackerDebugSizeEdt->setText(QString::number(ndsHeader->DebugSize,16));
|
|
||||||
ui->unpackerDebugRamAddrEdt->setText(QString::number(ndsHeader->DebugRamAddr,16));
|
|
||||||
|
|
||||||
ui->unpackerFatFilesOriginalAddrEdt->setText(QString::number((ndsHeader->IconTitleAddr+IconTitleSize),16));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::enableExtractionButtons()
|
|
||||||
{
|
|
||||||
ui->unpackerExtractorGbx->setEnabled(true);
|
|
||||||
ui->unpackerExtraGbx->setEnabled(true);
|
|
||||||
if (ui->unpackerARM9OverlayAddrEdt->text().toUInt(nullptr, 16) == 0){
|
|
||||||
ui->unpackerDumpArm9OverlayBtn->setEnabled(false);
|
|
||||||
ui->unpackerDumpArm9OverlayFilesBtn->setEnabled(false);
|
|
||||||
}
|
|
||||||
if (ui->unpackerARM7OverlayAddrEdt->text().toUInt(nullptr, 16) == 0){
|
|
||||||
ui->unpackerDumpArm7OverlayBtn->setEnabled(false);
|
|
||||||
ui->unpackerDumpArm7OverlayFilesBtn->setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::disableExtractionButtons()
|
|
||||||
{
|
|
||||||
ui->unpackerExtractorGbx->setEnabled(false);
|
|
||||||
ui->unpackerExtraGbx->setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpHeader(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
0,
|
|
||||||
ui->unpackerHeaderSizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpArm9Bin(const std::string& dirPath, bool dumpExtraBytes)
|
|
||||||
{
|
|
||||||
uint32_t size = ui->unpackerARM9SizeEdt->text().toUInt(nullptr, 16);
|
|
||||||
if (dumpExtraBytes)
|
|
||||||
size += 12;
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerARM9RomAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpArm7Bin(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerARM7RomAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->unpackerARM7SizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpFnt(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerFilenameTableAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->unpackerFilenameTableSizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpFat(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerFATAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->unpackerFATSizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpArm9Overlay(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerARM9OverlayAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->unpackerARM9OverlaySizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpArm9OverlayFiles(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return false; // TODO: implement me!
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpArm7Overlay(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerARM7OverlayAddrEdt->text().toUInt(nullptr, 16),
|
|
||||||
ui->unpackerARM7OverlaySizeEdt->text().toUInt(nullptr, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpArm7OverlayFiles(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return false; // TODO: implement me!
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpIconTitle(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
ui->unpackerIconTitleEdt->text().toUInt(nullptr, 16),
|
|
||||||
0xA00);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::dumpFatFiles(const std::string& dirPath)
|
|
||||||
{
|
|
||||||
uint32_t startAddr = ui->unpackerIconTitleEdt->text().toUInt(nullptr, 16) + IconTitleSize;
|
|
||||||
uint32_t size = ui->unpackerUsedRomSizeEdt->text().toUInt(nullptr, 16) - startAddr;
|
|
||||||
|
|
||||||
return ndsFactory.dumpDataFromFile(
|
|
||||||
ui->loadedRomPath->text().toStdString(),
|
|
||||||
dirPath,
|
|
||||||
startAddr,
|
|
||||||
size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool MainWindow::dumpEverything(QString dirPath)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(!dumpHeader(QDir::toNativeSeparators(dirPath+"/header.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(!dumpArm9Bin(QDir::toNativeSeparators(dirPath+"/arm9.bin").toStdString(), true))
|
|
||||||
return false;
|
|
||||||
if(!dumpArm7Bin(QDir::toNativeSeparators(dirPath+"/arm7.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(!dumpFnt(QDir::toNativeSeparators(dirPath+"/fnt.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(!dumpFat(QDir::toNativeSeparators(dirPath+"/fat.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(ui->unpackerARM9OverlayAddrEdt->text().toUInt(nullptr, 16) != 0) {
|
|
||||||
if(!dumpArm9Overlay(QDir::toNativeSeparators(dirPath+"/a9ovr.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(!dumpArm9OverlayFiles(QDir::toNativeSeparators(dirPath+"/a9ovr_data.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(ui->unpackerARM7OverlayAddrEdt->text().toUInt(nullptr, 16) != 0) {
|
|
||||||
if(!dumpArm7Overlay(QDir::toNativeSeparators(dirPath+"/a7ovr.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(!dumpArm7OverlayFiles(QDir::toNativeSeparators(dirPath+"/a7ovr_data.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!dumpIconTitle(QDir::toNativeSeparators(dirPath+"/itl.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
if(!dumpFatFiles(QDir::toNativeSeparators(dirPath+"/fat_data.bin").toStdString()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MainWindow::decodeFatFiles()
|
|
||||||
{
|
|
||||||
// TODO: implement me!
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user