Some notes for NPDM implementation
This commit is contained in:
parent
02b49d9cb2
commit
bd70a7db78
17 changed files with 719 additions and 15 deletions
|
@ -1,6 +1,6 @@
|
|||
# konogonka
|
||||
|
||||
Deep WIP multi-tool to work with XCI/NSP/NCA/NRO(?) files
|
||||
Deep WIP multi-tool to work with NS-specific files / filesystem images.
|
||||
|
||||
### License
|
||||
|
||||
|
@ -24,5 +24,6 @@ JRE/JDK 8u60 or higher.
|
|||
### Checklist
|
||||
|
||||
* [ ] LogPrinter to singleton implementation
|
||||
* [ ] NPDM support
|
||||
* [ ] CNMT support
|
||||
* [ ] support
|
||||
* [ ] NSO support
|
4
pom.xml
4
pom.xml
|
@ -8,11 +8,11 @@
|
|||
<name>konogonka</name>
|
||||
|
||||
<artifactId>konogonka</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<version>0.0-SNAPSHOT</version>
|
||||
|
||||
<url>https://github.com/developersu/${project.name}}/</url>
|
||||
<description>
|
||||
NSP and XCI multitool
|
||||
NS filesystem multitool
|
||||
</description>
|
||||
<inceptionYear>2019</inceptionYear>
|
||||
<organization>
|
||||
|
|
|
@ -8,6 +8,7 @@ import javafx.stage.FileChooser;
|
|||
import konogonka.AppPreferences;
|
||||
import konogonka.Child.ChildWindow;
|
||||
import konogonka.Controllers.NCA.NCAController;
|
||||
import konogonka.Controllers.NPDM.NPDMController;
|
||||
import konogonka.Controllers.NSP.NSPController;
|
||||
import konogonka.Controllers.TIK.TIKController;
|
||||
import konogonka.Controllers.XCI.XCIController;
|
||||
|
@ -50,6 +51,8 @@ public class MainController implements Initializable {
|
|||
private TIKController TIKTabController;
|
||||
@FXML
|
||||
private XMLController XMLTabController;
|
||||
@FXML
|
||||
private NPDMController NPDMTabController;
|
||||
|
||||
private File selectedFile;
|
||||
|
||||
|
@ -83,7 +86,7 @@ public class MainController implements Initializable {
|
|||
else
|
||||
fileChooser.setInitialDirectory(new File(System.getProperty("user.home")));
|
||||
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS files", "*.nsp", "*.xci", "*.nca", "*.tik", "*.xml"));
|
||||
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NS files", "*.nsp", "*.xci", "*.nca", "*.tik", "*.xml", "*.npdm"));
|
||||
|
||||
this.selectedFile = fileChooser.showOpenDialog(analyzeBtn.getScene().getWindow());
|
||||
|
||||
|
@ -93,6 +96,7 @@ public class MainController implements Initializable {
|
|||
NCATabController.resetTab();
|
||||
TIKTabController.resetTab();
|
||||
XMLTabController.resetTab();
|
||||
NPDMTabController.resetTab();
|
||||
|
||||
if (this.selectedFile != null && this.selectedFile.exists()) {
|
||||
filenameSelected.setText(this.selectedFile.getAbsolutePath());
|
||||
|
@ -108,6 +112,8 @@ public class MainController implements Initializable {
|
|||
tabPane.getSelectionModel().select(3);
|
||||
else if (this.selectedFile.getName().toLowerCase().endsWith(".xml"))
|
||||
tabPane.getSelectionModel().select(4);
|
||||
else if (this.selectedFile.getName().toLowerCase().endsWith(".npdm"))
|
||||
tabPane.getSelectionModel().select(5);
|
||||
}
|
||||
|
||||
logArea.clear();
|
||||
|
@ -126,6 +132,8 @@ public class MainController implements Initializable {
|
|||
TIKTabController.analyze(selectedFile);
|
||||
else if (selectedFile.getName().toLowerCase().endsWith("xml"))
|
||||
XMLTabController.analyze(selectedFile);
|
||||
else if (selectedFile.getName().toLowerCase().endsWith("npdm"))
|
||||
NPDMTabController.analyze(selectedFile);
|
||||
}
|
||||
@FXML
|
||||
private void showHideLogs(){
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package konogonka.Controllers.NPDM;
|
||||
|
||||
public class ACI0Provider {
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package konogonka.Controllers.NPDM;
|
||||
|
||||
public class ACIDProvider {
|
||||
}
|
110
src/main/java/konogonka/Controllers/NPDM/NPDMController.java
Normal file
110
src/main/java/konogonka/Controllers/NPDM/NPDMController.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
package konogonka.Controllers.NPDM;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import konogonka.Controllers.ITabController;
|
||||
import konogonka.Tools.NPDM.NPDMProvider;
|
||||
import konogonka.Workers.AnalyzerNPDM;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import static konogonka.LoperConverter.byteArrToHexString;
|
||||
|
||||
public class NPDMController implements ITabController {
|
||||
|
||||
@FXML
|
||||
private Label magicNumLbl,
|
||||
reserved1Lbl,
|
||||
MMUFlagsLbl,
|
||||
reserved2Lbl,
|
||||
mainThreadPrioLbl,
|
||||
mainThreadCoreNumLbl,
|
||||
reserved3Lbl,
|
||||
personalMmHeapSizeLbl,
|
||||
versionLbl,
|
||||
mainThreadStackSizeLbl,
|
||||
aci0offsetLbl,
|
||||
aci0sizeLbl,
|
||||
acidOffsetLbl,
|
||||
acidSizeLbl,
|
||||
npdmFileSize;
|
||||
|
||||
@FXML
|
||||
private TextField titleNameTf,
|
||||
productCodeTf,
|
||||
reserved4Tf;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) { }
|
||||
|
||||
@Override
|
||||
public void analyze(File file) { analyze(file, 0); }
|
||||
|
||||
@Override
|
||||
public void analyze(File file, long offset) {
|
||||
AnalyzerNPDM analyzerNPDM = new AnalyzerNPDM(file, offset);
|
||||
analyzerNPDM.setOnSucceeded(e->{
|
||||
NPDMProvider tik = analyzerNPDM.getValue();
|
||||
if (offset == 0)
|
||||
setData(tik, file);
|
||||
else
|
||||
setData(tik, null);
|
||||
});
|
||||
Thread workThread = new Thread(analyzerNPDM);
|
||||
workThread.setDaemon(true);
|
||||
workThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetTab() {
|
||||
magicNumLbl.setText("-");
|
||||
reserved1Lbl.setText("-");
|
||||
MMUFlagsLbl.setText("-");
|
||||
reserved2Lbl.setText("-");
|
||||
mainThreadPrioLbl.setText("-");
|
||||
mainThreadCoreNumLbl.setText("-");
|
||||
reserved3Lbl.setText("-");
|
||||
personalMmHeapSizeLbl.setText("-");
|
||||
versionLbl.setText("-");
|
||||
mainThreadStackSizeLbl.setText("-");
|
||||
aci0offsetLbl.setText("-");
|
||||
aci0sizeLbl.setText("-");
|
||||
acidOffsetLbl.setText("-");
|
||||
acidSizeLbl.setText("-");
|
||||
titleNameTf.setText("-");
|
||||
productCodeTf.setText("-");
|
||||
reserved4Tf.setText("-");
|
||||
npdmFileSize.setText("-");
|
||||
}
|
||||
private void setData(NPDMProvider npdmProvider, File file) {
|
||||
if (npdmProvider == null)
|
||||
return;
|
||||
if (file != null)
|
||||
npdmFileSize.setText(Long.toString(file.length()));
|
||||
else
|
||||
npdmFileSize.setText("skipping calculation for in-file ticket");
|
||||
|
||||
magicNumLbl.setText(npdmProvider.getMagicNum());
|
||||
reserved1Lbl.setText(byteArrToHexString(npdmProvider.getReserved1()));
|
||||
MMUFlagsLbl.setText(npdmProvider.getMMUFlags()+" (0b"+String.format("%8s", Integer.toBinaryString(npdmProvider.getMMUFlags() & 0xFF)).replace(' ', '0')+")");
|
||||
reserved2Lbl.setText(String.format("0x%02x", npdmProvider.getReserved2()));
|
||||
mainThreadPrioLbl.setText(Byte.toString(npdmProvider.getMainThreadPrio()));
|
||||
mainThreadCoreNumLbl.setText(Byte.toString(npdmProvider.getMainThreadCoreNum()));
|
||||
reserved3Lbl.setText(byteArrToHexString(npdmProvider.getReserved3()));
|
||||
personalMmHeapSizeLbl.setText(Integer.toString(npdmProvider.getPersonalMmHeapSize()));
|
||||
versionLbl.setText(Integer.toString(npdmProvider.getVersion()));
|
||||
mainThreadStackSizeLbl.setText(Long.toString(npdmProvider.getMainThreadStackSize()));
|
||||
titleNameTf.setText(npdmProvider.getTitleName());
|
||||
productCodeTf.setText(byteArrToHexString(npdmProvider.getProductCode()));
|
||||
reserved4Tf.setText(byteArrToHexString(npdmProvider.getReserved4()));
|
||||
aci0offsetLbl.setText(Long.toString(npdmProvider.getAci0offset()));
|
||||
aci0sizeLbl.setText(Long.toString(npdmProvider.getAci0size()));
|
||||
acidOffsetLbl.setText(Long.toString(npdmProvider.getAcidOffset()));
|
||||
acidSizeLbl.setText(Long.toString(npdmProvider.getAcidSize()));
|
||||
}
|
||||
|
||||
}
|
|
@ -48,9 +48,7 @@ public class TIKController implements ITabController {
|
|||
String key = rightsIdTf.getText();
|
||||
String value = titleKeyBlockStartTf.getText();
|
||||
int titleKeysCnt = AppPreferences.getInstance().getTitleKeysCount();
|
||||
System.out.println(key+" "+value+" "+titleKeysCnt);
|
||||
if (key.length() > 16 && ! (key.length() > 32) && value.length() == 32){
|
||||
System.out.println("OK");
|
||||
for (int i = 0; i < titleKeysCnt; i++){
|
||||
if (AppPreferences.getInstance().getTitleKeyPair(i)[0].equals(key))
|
||||
return;
|
||||
|
|
|
@ -51,7 +51,6 @@ public class XMLController implements ITabController {
|
|||
* Read from offset to length
|
||||
* */
|
||||
public void analyze(File file, long offset, long fileSize) {
|
||||
System.out.println(file.length()+" "+offset+" "+fileSize);
|
||||
try {
|
||||
if (fileSize > 10485760) // 10mB
|
||||
throw new Exception("XMLController -> analyze(): File is too big. It must be something wrong with it. Usually they're smaller");
|
||||
|
|
|
@ -11,6 +11,17 @@ public class LoperConverter {
|
|||
public static long getLElong(byte[] bytes, int fromOffset){
|
||||
return ByteBuffer.wrap(bytes, fromOffset, 0x8).order(ByteOrder.LITTLE_ENDIAN).getLong();
|
||||
}
|
||||
/**
|
||||
* Convert int to long. Workaround to store unsigned int
|
||||
* @param bytes original array
|
||||
* @param fromOffset start position of the 4-bytes value
|
||||
* */
|
||||
public static long getLElongOfInt(byte[] bytes, int fromOffset){
|
||||
final byte[] holder = new byte[8];
|
||||
System.arraycopy(bytes, fromOffset, holder, 0, 4);
|
||||
return ByteBuffer.wrap(holder).order(ByteOrder.LITTLE_ENDIAN).getLong();
|
||||
}
|
||||
|
||||
public static String byteArrToHexString(byte[] bArr){
|
||||
if (bArr == null)
|
||||
return "";
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Locale;
|
|||
import java.util.ResourceBundle;
|
||||
|
||||
public class MainFx extends Application {
|
||||
public static final String appVersion = "v0.1-DEV";
|
||||
public static final String appVersion = "v0.0-SNAPSHOT";
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception{
|
||||
|
|
77
src/main/java/konogonka/Tools/NPDM/NPDMProvider.java
Normal file
77
src/main/java/konogonka/Tools/NPDM/NPDMProvider.java
Normal file
|
@ -0,0 +1,77 @@
|
|||
package konogonka.Tools.NPDM;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static konogonka.LoperConverter.*;
|
||||
|
||||
public class NPDMProvider {
|
||||
|
||||
private String magicNum;
|
||||
private byte[] reserved1;
|
||||
private byte MMUFlags;
|
||||
private byte reserved2;
|
||||
private byte mainThreadPrio;
|
||||
private byte mainThreadCoreNum;
|
||||
private byte[] reserved3;
|
||||
private int personalMmHeapSize; // safe-to-store
|
||||
private int version; // safe?
|
||||
private long mainThreadStackSize; // TODO: check if safe
|
||||
private String titleName;
|
||||
private byte[] productCode;
|
||||
private byte[] reserved4;
|
||||
private long aci0offset; // originally 4-bytes (u-int)
|
||||
private long aci0size; // originally 4-bytes (u-int)
|
||||
private long acidOffset; // originally 4-bytes (u-int)
|
||||
private long acidSize; // originally 4-bytes (u-int)
|
||||
|
||||
public NPDMProvider(File file) throws Exception { this(file, 0); }
|
||||
|
||||
public NPDMProvider(File file, long offset) throws Exception {
|
||||
if (file.length() - offset < 0x80) // Header's size
|
||||
throw new Exception("NPDMProvider: File is too small.");
|
||||
RandomAccessFile raf = new RandomAccessFile(file, "r");
|
||||
raf.seek(offset);
|
||||
// Get META
|
||||
byte[] metaBuf = new byte[0x80];
|
||||
if (raf.read(metaBuf) != 0x80)
|
||||
throw new Exception("NPDMProvider: Failed to read 'META'");
|
||||
magicNum = new String(metaBuf, 0, 4, StandardCharsets.UTF_8);
|
||||
reserved1 = Arrays.copyOfRange(metaBuf, 0x4, 0xC);
|
||||
MMUFlags = metaBuf[0xC];
|
||||
reserved2 = metaBuf[0xD];
|
||||
mainThreadPrio = metaBuf[0xE];
|
||||
mainThreadCoreNum = metaBuf[0xF];
|
||||
reserved3 = Arrays.copyOfRange(metaBuf, 0x10, 0x14);
|
||||
personalMmHeapSize = getLEint(metaBuf, 0x14);
|
||||
version = getLEint(metaBuf, 0x18);
|
||||
mainThreadStackSize = getLElongOfInt(metaBuf, 0x1C);
|
||||
titleName = new String(metaBuf, 0x20, 0x10, StandardCharsets.UTF_8);
|
||||
productCode = Arrays.copyOfRange(metaBuf, 0x30, 0x40);
|
||||
reserved4 = Arrays.copyOfRange(metaBuf, 0x40, 0x70);
|
||||
aci0offset = getLElongOfInt(metaBuf, 0x70);
|
||||
aci0size = getLElongOfInt(metaBuf, 0x74);
|
||||
acidOffset = getLElongOfInt(metaBuf, 0x78);
|
||||
acidSize = getLElongOfInt(metaBuf, 0x7C);
|
||||
}
|
||||
|
||||
public String getMagicNum() { return magicNum; }
|
||||
public byte[] getReserved1() { return reserved1; }
|
||||
public byte getMMUFlags() { return MMUFlags; }
|
||||
public byte getReserved2() { return reserved2; }
|
||||
public byte getMainThreadPrio() { return mainThreadPrio; }
|
||||
public byte getMainThreadCoreNum() { return mainThreadCoreNum; }
|
||||
public byte[] getReserved3() { return reserved3; }
|
||||
public int getPersonalMmHeapSize() { return personalMmHeapSize; }
|
||||
public int getVersion() { return version; }
|
||||
public long getMainThreadStackSize() { return mainThreadStackSize; }
|
||||
public String getTitleName() { return titleName; }
|
||||
public byte[] getProductCode() { return productCode; }
|
||||
public byte[] getReserved4() { return reserved4; }
|
||||
public long getAci0offset() { return aci0offset; }
|
||||
public long getAci0size() { return aci0size; }
|
||||
public long getAcidOffset() { return acidOffset; }
|
||||
public long getAcidSize() { return acidSize; }
|
||||
}
|
|
@ -1,8 +1,5 @@
|
|||
package konogonka.Tools.PFS0;
|
||||
|
||||
import konogonka.ModelControllers.EMsgType;
|
||||
import konogonka.RainbowHexDump;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
|
|
@ -3,7 +3,6 @@ package konogonka.Workers;
|
|||
import javafx.concurrent.Task;
|
||||
import konogonka.ModelControllers.EMsgType;
|
||||
import konogonka.ModelControllers.LogPrinter;
|
||||
import konogonka.Tools.ISuperProvider;
|
||||
import konogonka.Tools.NCA.NCAProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
|
46
src/main/java/konogonka/Workers/AnalyzerNPDM.java
Normal file
46
src/main/java/konogonka/Workers/AnalyzerNPDM.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package konogonka.Workers;
|
||||
|
||||
import javafx.concurrent.Task;
|
||||
import konogonka.ModelControllers.EMsgType;
|
||||
import konogonka.ModelControllers.LogPrinter;
|
||||
import konogonka.Tools.NPDM.NPDMProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class AnalyzerNPDM extends Task<NPDMProvider> {
|
||||
|
||||
private File file;
|
||||
private long offset;
|
||||
private LogPrinter logPrinter;
|
||||
|
||||
public AnalyzerNPDM(File file){
|
||||
this(file, 0);
|
||||
}
|
||||
|
||||
public AnalyzerNPDM(File file, long offset){
|
||||
this.file = file;
|
||||
this.offset = offset;
|
||||
this.logPrinter = new LogPrinter();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NPDMProvider call() {
|
||||
logPrinter.print("\tStart chain: NPDM", EMsgType.INFO);
|
||||
try{
|
||||
return new NPDMProvider(file, offset);
|
||||
}
|
||||
catch (Exception e){
|
||||
logPrinter.print("\tException: "+e.getMessage(), EMsgType.FAIL);
|
||||
return null;
|
||||
}
|
||||
finally {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
private void close(){
|
||||
logPrinter.print("\tEnd chain: NPDM", EMsgType.INFO);
|
||||
logPrinter.close();
|
||||
}
|
||||
}
|
||||
|
442
src/main/resources/FXML/NPDM/NPDMTab.fxml
Normal file
442
src/main/resources/FXML/NPDM/NPDMTab.fxml
Normal file
|
@ -0,0 +1,442 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<ScrollPane fitToWidth="true" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="konogonka.Controllers.NPDM.NPDMController">
|
||||
<VBox spacing="5.0">
|
||||
<Label text="META">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<GridPane gridLinesVisible="true">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="60.0" minWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="60.0" minWidth="55.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="430.0" minWidth="300.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="30.0" minHeight="30.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="1">
|
||||
<children>
|
||||
<Label layoutX="38.0" layoutY="6.0" text="Size" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="2">
|
||||
<children>
|
||||
<Label layoutX="14.0" layoutY="7.0" text="Description" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid" GridPane.columnIndex="3">
|
||||
<children>
|
||||
<Label layoutY="6.0" text="Value" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane styleClass="customTitleGrid">
|
||||
<children>
|
||||
<Label layoutX="2.0" layoutY="7.0" text="Offset" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||
<font>
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<Label text="0x0" GridPane.rowIndex="1">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x1" GridPane.columnIndex="1" GridPane.rowIndex="5">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0xE" GridPane.rowIndex="5">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x1" GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0xD" GridPane.rowIndex="4">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x1" GridPane.columnIndex="1" GridPane.rowIndex="3">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0xC" GridPane.rowIndex="3">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x8" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.rowIndex="2">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0xF" GridPane.rowIndex="6">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x1" GridPane.columnIndex="1" GridPane.rowIndex="6">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x10" GridPane.rowIndex="7">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="7">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x14" GridPane.rowIndex="8">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="8">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x18" GridPane.rowIndex="9">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="9">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x1C" GridPane.rowIndex="10">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="10">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x20" GridPane.rowIndex="11">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x10" GridPane.columnIndex="1" GridPane.rowIndex="11">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Magicnum "META"" GridPane.columnIndex="2" GridPane.rowIndex="1">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Reserved (1)" GridPane.columnIndex="2" GridPane.rowIndex="2">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="MMU flags*" GridPane.columnIndex="2" GridPane.rowIndex="3">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x30" GridPane.rowIndex="12">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x10" GridPane.columnIndex="1" GridPane.rowIndex="12">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x40" GridPane.rowIndex="13">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x30" GridPane.columnIndex="1" GridPane.rowIndex="13">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x70" GridPane.rowIndex="14">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="16">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="15">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x74" GridPane.rowIndex="15">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x78" GridPane.rowIndex="16">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Reserved (3)" GridPane.columnIndex="2" GridPane.rowIndex="7">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="14">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Reserved (2)" GridPane.columnIndex="2" GridPane.rowIndex="4">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x7C" GridPane.rowIndex="17">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="0x4" GridPane.columnIndex="1" GridPane.rowIndex="17">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Main thread priority (0-63)" GridPane.columnIndex="2" GridPane.rowIndex="5">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Main thread core number" GridPane.columnIndex="2" GridPane.rowIndex="6">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="magicNumLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="1">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="reserved1Lbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="2">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="[3.0.0+] System resource (PersonalMmHeap) size" GridPane.columnIndex="2" GridPane.rowIndex="8">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Version (0 for all titles prior to 8.1.0, 1 for certain titles since)." GridPane.columnIndex="2" GridPane.rowIndex="9">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Main thread stack size***" GridPane.columnIndex="2" GridPane.rowIndex="10">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Title name (usually/always "Application")" GridPane.columnIndex="2" GridPane.rowIndex="11">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Product code (usually/always all zeroes)" GridPane.columnIndex="2" GridPane.rowIndex="12">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="ACI0 size" GridPane.columnIndex="2" GridPane.rowIndex="15">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Reserved (4)" GridPane.columnIndex="2" GridPane.rowIndex="13">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="ACI0 offset" GridPane.columnIndex="2" GridPane.rowIndex="14">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="ACID offset" GridPane.columnIndex="2" GridPane.rowIndex="16">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="MMUFlagsLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="3">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="ACID size" GridPane.columnIndex="2" GridPane.rowIndex="17">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="reserved2Lbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="4">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="mainThreadPrioLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="5">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="mainThreadCoreNumLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="6">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="reserved3Lbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="7">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="personalMmHeapSizeLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="8">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="versionLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="9">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="mainThreadStackSizeLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="10">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="aci0offsetLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="14">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="aci0sizeLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="15">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="acidOffsetLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="16">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Label fx:id="acidSizeLbl" text="-" GridPane.columnIndex="3" GridPane.rowIndex="17">
|
||||
<padding>
|
||||
<Insets left="5.0" right="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<TextField fx:id="titleNameTf" GridPane.columnIndex="3" GridPane.rowIndex="11" />
|
||||
<TextField fx:id="productCodeTf" GridPane.columnIndex="3" GridPane.rowIndex="12" />
|
||||
<TextField fx:id="reserved4Tf" GridPane.columnIndex="3" GridPane.rowIndex="13" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<Label text="* bit0 = use 64-bit instructions, bit1 = use 64-bit address space, bit2 = use 32-bit address space, bit3 = use 32-bit address space without reserved region, bit4 = optimize memory allocation?" />
|
||||
<Label text="** max size as of 5.x: 534773760" />
|
||||
<Label text="*** Should(?) be page-aligned. In non-nspwn scenarios, values of 0 can also rarely break in Horizon. This might be something auto-adapting or a security feature of some sort?" />
|
||||
<HBox spacing="5.0">
|
||||
<children>
|
||||
<Label text="File size" />
|
||||
<Label text=":" />
|
||||
<Label fx:id="npdmFileSize" text="-" />
|
||||
</children>
|
||||
</HBox>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
</ScrollPane>
|
|
@ -14,7 +14,7 @@
|
|||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<VBox xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="konogonka.Settings.SettingsController">
|
||||
<VBox xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="konogonka.Settings.SettingsController">
|
||||
<children>
|
||||
<TabPane side="LEFT" tabClosingPolicy="UNAVAILABLE" tabMaxHeight="100.0" tabMaxWidth="80.0" tabMinHeight="80.0" tabMinWidth="50.0" VBox.vgrow="ALWAYS">
|
||||
<tabs>
|
||||
|
@ -101,7 +101,7 @@
|
|||
<graphic>
|
||||
<VBox alignment="TOP_CENTER" spacing="5.0">
|
||||
<children>
|
||||
<SVGPath content="M22,18V22H18V19H15V16H12L9.74,13.74C9.19,13.91 8.61,14 8,14A6,6 0 0,1 2,8A6,6 0 0,1 8,2A6,6 0 0,1 14,8C14,8.61 13.91,9.19 13.74,9.74L22,18M7,5A2,2 0 0,0 5,7A2,2 0 0,0 7,9A2,2 0 0,0 9,7A2,2 0 0,0 7,5Z" />
|
||||
<SVGPath content="M7,6H17A6,6 0 0,1 23,12A6,6 0 0,1 17,18C15.22,18 13.63,17.23 12.53,16H11.47C10.37,17.23 8.78,18 7,18A6,6 0 0,1 1,12A6,6 0 0,1 7,6M6,9V11H4V13H6V15H8V13H10V11H8V9H6M15.5,12A1.5,1.5 0 0,0 14,13.5A1.5,1.5 0 0,0 15.5,15A1.5,1.5 0 0,0 17,13.5A1.5,1.5 0 0,0 15.5,12M18.5,9A1.5,1.5 0 0,0 17,10.5A1.5,1.5 0 0,0 18.5,12A1.5,1.5 0 0,0 20,10.5A1.5,1.5 0 0,0 18.5,9Z" />
|
||||
<Label text="title.keys" />
|
||||
</children>
|
||||
</VBox>
|
||||
|
|
|
@ -87,6 +87,14 @@
|
|||
<Label text="XML" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
<Tab closable="false">
|
||||
<content>
|
||||
<fx:include fx:id="NPDMTab" source="NPDM/NPDMTab.fxml" />
|
||||
</content>
|
||||
<graphic>
|
||||
<Label text="NPDM" />
|
||||
</graphic>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
<AnchorPane fx:id="logPane" prefHeight="200.0" prefWidth="200.0">
|
||||
|
|
Loading…
Reference in a new issue