Implement Nissan STD checksum validation and calculation

This commit is contained in:
Dale Schultz 2017-07-04 18:07:53 -04:00
parent dfa6ff7ffd
commit c05c56b5fd
8 changed files with 400 additions and 115 deletions

View File

@ -1,6 +1,6 @@
/* /*
* RomRaider Open-Source Tuning, Logging and Reflashing * RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2014 RomRaider.com * Copyright (C) 2006-2017 RomRaider.com
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -716,6 +716,11 @@ class OpenImageWorker extends SwingWorker<Void, Void> {
editor.refreshTableCompareMenus(); editor.refreshTableCompareMenus();
editor.getStatusPanel().setStatus("Done loading image..."); editor.getStatusPanel().setStatus("Done loading image...");
setProgress(95);
editor.getStatusPanel().setStatus("Validating checksum...");
rom.validateChecksum();
setProgress(100); setProgress(100);
return null; return null;
} }

View File

@ -1,6 +1,6 @@
/* /*
* RomRaider Open-Source Tuning, Logging and Reflashing * RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2016 RomRaider.com * Copyright (C) 2006-2017 RomRaider.com
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,6 +24,8 @@ import static com.romraider.util.HexUtil.asBytes;
import static com.romraider.util.HexUtil.asHex; import static com.romraider.util.HexUtil.asHex;
import static javax.swing.JOptionPane.DEFAULT_OPTION; import static javax.swing.JOptionPane.DEFAULT_OPTION;
import static javax.swing.JOptionPane.QUESTION_MESSAGE; import static javax.swing.JOptionPane.QUESTION_MESSAGE;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import static javax.swing.JOptionPane.showOptionDialog; import static javax.swing.JOptionPane.showOptionDialog;
import java.beans.PropertyVetoException; import java.beans.PropertyVetoException;
@ -43,6 +45,7 @@ import org.apache.log4j.Logger;
import com.romraider.Settings; import com.romraider.Settings;
import com.romraider.logger.ecu.ui.handler.table.TableUpdateHandler; import com.romraider.logger.ecu.ui.handler.table.TableUpdateHandler;
import com.romraider.maps.checksum.ChecksumManager;
import com.romraider.swing.CategoryTreeNode; import com.romraider.swing.CategoryTreeNode;
import com.romraider.swing.JProgressPane; import com.romraider.swing.JProgressPane;
import com.romraider.swing.TableFrame; import com.romraider.swing.TableFrame;
@ -60,6 +63,7 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
private final Vector<TableTreeNode> tableNodes = new Vector<TableTreeNode>(); private final Vector<TableTreeNode> tableNodes = new Vector<TableTreeNode>();
private byte[] binData; private byte[] binData;
private boolean isAbstract = false; private boolean isAbstract = false;
private ChecksumManager checksumManager;
public Rom() { public Rom() {
tableNodes.clear(); tableNodes.clear();
@ -354,6 +358,7 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
} }
} }
} }
updateChecksum();
return binData; return binData;
} }
@ -416,4 +421,35 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
public DefaultMutableTreeNode getLastChild() { public DefaultMutableTreeNode getLastChild() {
return (DefaultMutableTreeNode) super.getLastChild(); return (DefaultMutableTreeNode) super.getLastChild();
} }
public void setChecksumManager(ChecksumManager checksumManager) {
this.checksumManager = checksumManager;
}
public ChecksumManager getChecksumType() {
return checksumManager;
}
public void validateChecksum() {
if (checksumManager != null) {
final String message = String.format(
"Checksum is invalid.%n" +
"The ROM image may be corrupt or it has been " +
"hex edited manually.%n" +
"The checksum can be corrected when the ROM " +
"is saved if your trust it is not corrupt.");
if (!checksumManager.validate(binData)) {
showMessageDialog(null,
message,
"ERROR - Checksum Failed",
WARNING_MESSAGE);
}
}
}
public void updateChecksum() {
if (checksumManager != null) {
checksumManager.update(binData);
}
}
} }

View File

@ -43,6 +43,7 @@ public class RomID implements Serializable {
private int fileSize; private int fileSize;
private int ramOffset; private int ramOffset;
private boolean obsolete; // whether a more recent revision exists private boolean obsolete; // whether a more recent revision exists
private String checksum; // checksum method used to validate ROM contents
public String toString() { public String toString() {
return String.format( return String.format(
@ -216,4 +217,12 @@ public class RomID implements Serializable {
public void setEditStamp(String editStamp) { public void setEditStamp(String editStamp) {
this.editStamp = editStamp; this.editStamp = editStamp;
} }
public void setChecksum(String checksum) {
this.checksum = checksum;
}
public String getChecksum() {
return checksum;
}
} }

View File

@ -0,0 +1,74 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2017 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.romraider.maps.checksum;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog;
import java.util.Map;
/**
* Instantiate a ChecksumManager class.
*/
public final class ChecksumFactory {
private static final String TYPE = "type";
private static final String MISSING =
"Error in checksum definition, 'type' attribute missing.";
private static final String NO_CLASS =
"Error loading Checksum Manager of type: %s";
private ChecksumFactory() {
}
/**
* Instantiate the specific ChecksumManager class based on
* the "type" requested.
* @param attrs - the configuration for the checksum manager, must
* contain a "type" K,V pair
* @return a configured instance of the requested ChecksumManager
* @throws ClassNotFoundException if the class based on "type"
* does not exist
*/
public static ChecksumManager getManager(
Map<String, String> attrs) {
ChecksumManager cm = null;
Class<?> cls;
final String type = attrs.get(TYPE);
try {
cls = Class.forName(
ChecksumFactory.class.getPackage().getName() +
".Checksum" + type.toUpperCase());
cm = (ChecksumManager) cls.newInstance();
cm.configure(attrs);
} catch (Exception e) {
String message = null;
if (type == null) {
message = MISSING;
}
else {
message = String.format(NO_CLASS, type.toUpperCase());
}
showMessageDialog(null,
message,
"Error Loading Checksum Manager", ERROR_MESSAGE);
}
return cm;
}
}

View File

@ -0,0 +1,51 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2017 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.romraider.maps.checksum;
import java.util.Map;
/**
* The Checksum Manager interface is implemented by Checksum classes
* which perform validation and calculation of ROM checksums upon open
* and save.
*/
public interface ChecksumManager {
/**
* Once the ChecksumManager is created configure it with the
* information needed to perform checksums.
* @param vars - a map of variables specific to the type of
* checksums being performed
*/
void configure(Map<String, String> vars);
/**
* Perform the checksum validation upon ROM file loading.
* @param binData - the ROM file to validate
* @return true or false, the result of validation
*/
boolean validate(byte[] data);
/**
* Update the checksum upon saving the ROM file.
* @param data - the ROM file to update
*/
void update(byte[] data);
}

View File

@ -0,0 +1,83 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2017 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.romraider.maps.checksum;
import static com.romraider.xml.RomAttributeParser.parseByteValue;
import static com.romraider.xml.RomAttributeParser.parseIntegerValue;
import java.util.Map;
import com.romraider.util.HexUtil;
/**
* This class implements the "std" checksum validation and calculations
* for Nissan ROMs.
*/
public final class ChecksumSTD implements ChecksumManager {
private static final String START = "start";
private static final String END = "end";
private static final String SUMLOC = "sumloc";
private static final String XORLOC = "xorloc";
private int start;
private int end;
private int sumloc;
private int xorloc;
private int sumt;
private int xort;
public ChecksumSTD() {
}
@Override
public void configure(Map<String, String> vars) {
this.start = HexUtil.hexToInt(vars.get(START));
this.end = HexUtil.hexToInt(vars.get(END));
this.sumloc = HexUtil.hexToInt(vars.get(SUMLOC));
this.xorloc = HexUtil.hexToInt(vars.get(XORLOC));
}
@Override
public boolean validate(byte[] binData) {
calculate(binData);
final boolean valid =
(sumt == (int)parseByteValue(binData, 0, sumloc, 4, true)) &&
(xort == (int)parseByteValue(binData, 0, xorloc, 4, true));
return valid;
}
@Override
public void update(byte[] binData) {
calculate(binData);
System.arraycopy(parseIntegerValue(sumt, 0, 4), 0, binData, sumloc, 4);
System.arraycopy(parseIntegerValue(xort, 0, 4), 0, binData, xorloc, 4);
}
private void calculate(byte[] binData) {
sumt = 0;
xort = 0;
int dw = 0;
for (int i = start; i < end; i += 4) {
if ((i == sumloc) || (i == xorloc)) continue;
dw = (int)parseByteValue(binData, 0, i, 4, true);
sumt += dw;
xort ^= dw;
}
}
}

View File

@ -1,6 +1,6 @@
/* /*
* RomRaider Open-Source Tuning, Logging and Reflashing * RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2012 RomRaider.com * Copyright (C) 2006-2017 RomRaider.com
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,6 +22,8 @@ package com.romraider.swing;
import com.romraider.maps.Rom; import com.romraider.maps.Rom;
import javax.swing.*; import javax.swing.*;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;
public class RomPropertyPanel extends javax.swing.JPanel { public class RomPropertyPanel extends javax.swing.JPanel {
@ -46,6 +48,7 @@ public class RomPropertyPanel extends javax.swing.JPanel {
submodel.setText(rom.getRomID().getSubModel()); submodel.setText(rom.getRomID().getSubModel());
transmission.setText(rom.getRomID().getTransmission()); transmission.setText(rom.getRomID().getTransmission());
editStamp.setText(rom.getRomID().getEditStamp()); editStamp.setText(rom.getRomID().getEditStamp());
checksum.setText(rom.getRomID().getChecksum());
tableList.setListData(rom.getTables()); tableList.setListData(rom.getTables());
} }
@ -81,6 +84,12 @@ public class RomPropertyPanel extends javax.swing.JPanel {
lblTables = new javax.swing.JLabel(); lblTables = new javax.swing.JLabel();
lblEditStamp = new javax.swing.JLabel(); lblEditStamp = new javax.swing.JLabel();
editStamp = new javax.swing.JLabel(); editStamp = new javax.swing.JLabel();
lblChecksum = new javax.swing.JLabel();
checksum = new javax.swing.JLabel();
lblChecksum.setText("Checksum:");
checksum.setText("subaru");
lblEditStamp.setText("Edit Stamp:"); lblEditStamp.setText("Edit Stamp:");
@ -154,122 +163,115 @@ public class RomPropertyPanel extends javax.swing.JPanel {
lblTables.setText("Tables:"); lblTables.setText("Tables:");
GroupLayout layout = new GroupLayout(this); GroupLayout layout = new GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING) layout.createParallelGroup(Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addComponent(lblFilename)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addPreferredGap(ComponentPlacement.RELATED)
.addGroup(layout.createSequentialGroup() .addComponent(fileName, GroupLayout.PREFERRED_SIZE, 302, GroupLayout.PREFERRED_SIZE))
.addComponent(lblFilename) .addGroup(layout.createSequentialGroup()
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(fileName, GroupLayout.PREFERRED_SIZE, 302, GroupLayout.PREFERRED_SIZE)) .addComponent(lblECURevision)
.addGroup(layout.createSequentialGroup() .addComponent(lblEcuVersion)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(lblFilesize)
.addGroup(layout.createSequentialGroup() .addComponent(lblChecksum)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(lblMake)
.addComponent(lblECURevision) .addComponent(lblMarket)
.addComponent(lblEcuVersion) .addComponent(lblYear)
.addComponent(lblFilesize)) .addComponent(lblModel)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblSubmodel)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(lblTransmission))
.addComponent(fileSize) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(ecuVersion) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(xmlID))) .addComponent(transmission)
.addGroup(layout.createSequentialGroup() .addComponent(submodel)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(model)
.addComponent(lblYear) .addComponent(year)
.addComponent(lblModel) .addComponent(market)
.addComponent(lblSubmodel) .addComponent(make)
.addComponent(lblTransmission) .addComponent(checksum, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE)
.addComponent(lblMarket) .addComponent(fileSize)
.addComponent(lblMake)) .addComponent(ecuVersion)
.addGap(7, 7, 7) .addComponent(xmlID))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGap(20)
.addComponent(make) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(market) .addComponent(lblTables)
.addComponent(year) .addComponent(lblEditStamp)
.addGroup(layout.createSequentialGroup() .addComponent(lblStorageAddress)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblInternalId))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGap(18)
.addComponent(transmission) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(submodel))) .addComponent(editStamp)
.addComponent(model)))) .addComponent(storageAddress)
.addGap(32, 32, 32) .addComponent(internalID)))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup()
.addGroup(layout.createSequentialGroup() .addGap(163)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 226, GroupLayout.PREFERRED_SIZE)))
.addComponent(lblInternalId) .addContainerGap(51, Short.MAX_VALUE))
.addComponent(lblStorageAddress)
.addComponent(lblEditStamp))
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 53, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addComponent(internalID)
.addComponent(storageAddress)
.addComponent(editStamp))
.addGap(36, 36, 36))
.addComponent(lblTables)
.addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 226, GroupLayout.PREFERRED_SIZE))))
.addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
layout.createParallelGroup(GroupLayout.Alignment.LEADING) layout.createParallelGroup(Alignment.TRAILING)
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21) .addGap(21)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(lblFilename)
.addComponent(lblFilename) .addComponent(fileName))
.addComponent(fileName)) .addGap(26)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addGap(40, 40, 40) .addComponent(lblECURevision)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(xmlID)
.addComponent(lblECURevision) .addComponent(lblInternalId)
.addComponent(xmlID) .addComponent(internalID))
.addComponent(lblInternalId) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(internalID)) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblEcuVersion)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(ecuVersion)
.addComponent(ecuVersion) .addComponent(lblStorageAddress)
.addComponent(lblEcuVersion) .addComponent(storageAddress))
.addComponent(storageAddress) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblStorageAddress)) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblFilesize)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(fileSize)
.addComponent(lblFilesize) .addComponent(lblEditStamp)
.addComponent(fileSize) .addComponent(editStamp))
.addComponent(lblEditStamp) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(editStamp)))) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblChecksum)
.addComponent(lblTables) .addComponent(checksum)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(lblTables))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addPreferredGap(ComponentPlacement.RELATED)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addGroup(layout.createSequentialGroup()
.addComponent(lblMake) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(make)) .addComponent(lblMake)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(make))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblMarket) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(market)) .addComponent(lblMarket)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(market))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblYear) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(year)) .addComponent(lblYear)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(year))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblModel) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(model)) .addComponent(lblModel)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(model))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblSubmodel) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(submodel)) .addComponent(lblSubmodel)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(submodel))
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addPreferredGap(ComponentPlacement.RELATED)
.addComponent(lblTransmission) .addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(transmission))) .addComponent(lblTransmission)
.addComponent(jScrollPane1, 0, 0, Short.MAX_VALUE)) .addComponent(transmission)))
.addContainerGap()) .addComponent(jScrollPane1, 0, 0, Short.MAX_VALUE))
.addContainerGap())
); );
this.setLayout(layout);
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
@ -302,6 +304,8 @@ public class RomPropertyPanel extends javax.swing.JPanel {
private javax.swing.JLabel year; private javax.swing.JLabel year;
private javax.swing.JLabel lblEditStamp; private javax.swing.JLabel lblEditStamp;
private javax.swing.JLabel editStamp; private javax.swing.JLabel editStamp;
private javax.swing.JLabel lblChecksum;
private javax.swing.JLabel checksum;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -1,6 +1,6 @@
/* /*
* RomRaider Open-Source Tuning, Logging and Reflashing * RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2016 RomRaider.com * Copyright (C) 2006-2017 RomRaider.com
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -48,6 +48,8 @@ import com.romraider.maps.Table1D;
import com.romraider.maps.Table2D; import com.romraider.maps.Table2D;
import com.romraider.maps.Table3D; import com.romraider.maps.Table3D;
import com.romraider.maps.TableSwitch; import com.romraider.maps.TableSwitch;
import com.romraider.maps.checksum.ChecksumFactory;
import com.romraider.maps.checksum.ChecksumManager;
import com.romraider.swing.DebugPanel; import com.romraider.swing.DebugPanel;
import com.romraider.swing.JProgressPane; import com.romraider.swing.JProgressPane;
import com.romraider.util.ObjectCloner; import com.romraider.util.ObjectCloner;
@ -61,6 +63,7 @@ public final class DOMRomUnmarshaller {
private String memModelEndian = null; private String memModelEndian = null;
private final Scale rawScale = new Scale(); private final Scale rawScale = new Scale();
private final Map<String, Integer> tableNames = new HashMap<String, Integer>(); private final Map<String, Integer> tableNames = new HashMap<String, Integer>();
private ChecksumManager checksumManager = null;
public DOMRomUnmarshaller() { public DOMRomUnmarshaller() {
} }
@ -107,6 +110,7 @@ public final class DOMRomUnmarshaller {
output.getRomID().setRamOffset( output.getRomID().setRamOffset(
output.getRomID().getFileSize() output.getRomID().getFileSize()
- input.length); - input.length);
output.setChecksumManager(checksumManager);
return output; return output;
} }
} }
@ -230,6 +234,9 @@ public final class DOMRomUnmarshaller {
} catch (XMLParseException ex) { } catch (XMLParseException ex) {
LOGGER.error("Error unmarshalling rom", ex); LOGGER.error("Error unmarshalling rom", ex);
} }
} else if (n.getNodeName().equalsIgnoreCase("checksum")) {
rom.getRomID().setChecksum(unmarshallAttribute(n, "type", ""));
checksumManager = unmarshallChecksum(n);
} else { /* unexpected element in Rom (skip) */ } else { /* unexpected element in Rom (skip) */
} }
@ -674,4 +681,20 @@ public final class DOMRomUnmarshaller {
} }
} }
} }
/**
* Unmarshall the attributes of the checksum element and populate a
* CheckSumManager object to be assigned to the ROM.
* @param node - the checksum element node to process
* @return CheckSumManager object
*/
private ChecksumManager unmarshallChecksum(Node node) {
final Map<String, String> attrs = new HashMap<String, String>();
for (int i = 0; i < node.getAttributes().getLength(); i++) {
attrs.put(node.getAttributes().item(i).getNodeName().toLowerCase(),
node.getAttributes().item(i).getNodeValue());
}
return ChecksumFactory.getManager(attrs);
}
} }