Changeset 327


Ignore:
Timestamp:
09/12/2011 08:39:19 PM (21 months ago)
Author:
dschultzca
Message:

--- Editor ---

  • Added support for multiple-state switches. This will result in a Switch Table being rendered with Radio Buttons rather than a checkbox.
  • Added ECU defintion data validation for Switch Tables. If the ROM image data does not match one of the switch states according to the definition then a warning is presented and the table is locked from editing.
  • Added ROM Checksum validation on image open for 32 bit ROMs. An ERROR message is presented warning not to use the ROM image as it may be corrupt.
  • Added ROM Checksum calculation for 32 bit ROMs. Upon file save the new Checksums (if not previously disabled) are written to the ROM.
  • Added a ROM Edit Stamp to 32 bit ROMs consisting of the YYMMDD and an incremental count value. This Edit Stamp is displayed in the View->ROM properties menu item.

--- Logger ---

  • Added more selection to the Right-click menu associated with the LogFile? text field.
Location:
trunk
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/release_notes.txt

    r326 r327  
    1                     - RomRaider 0.5.3 Beta RC9 - 
     1                    - RomRaider 0.5.3 Beta RC10 - 
    22            Open-Source ECU Tuning -- www.romraider.com 
    33 
     
    3535 
    3636------------------------------- 
    37 - 0.5.3b RC9 Notes (06/30/2011) - 
     37- 0.5.3b RC10 Notes (09/12/2011) - 
    3838------------------------------- 
    39 This is the nineth beta release of the upcoming official 0.5.3b release. 
     39This is the tenth beta release of the upcoming official 0.5.3b release. 
    4040 
    4141--------------------------- 
    42 - 0.5.3b RC9 Known Issues - 
     42- 0.5.3b RC10 Known Issues - 
    4343--------------------------- 
    4444- Editor 
     
    5555- Change Log - 
    5656-------------- 
     57 
     580.5.3b RC10 (09/12/2011) 
     59----------------------- 
     60 
     61--- Editor --- 
     62- Added support for multiple-state switches.  This will result in a Switch Table 
     63  being rendered with Radio Buttons rather than a checkbox. 
     64- Added ECU defintion data validation for Switch Tables.  If the ROM image data 
     65  does not match one of the switch states according to the definition then a 
     66  warning is presented and the table is locked from editing. 
     67- Added ROM Checksum validation on image open for 32 bit ROMs.  An ERROR message 
     68  is presented warning not to use the ROM image as it may be corrupt. 
     69- Added ROM Checksum calculation for 32 bit ROMs.  Upon file save the new 
     70  Checksums (if not previously disabled) are written to the ROM. 
     71- Added a ROM Edit Stamp to 32 bit ROMs consisting of the YYMMDD and an 
     72  incremental count value.  This Edit Stamp is displayed in the View->ROM 
     73  properties menu item. 
     74--- Logger --- 
     75- Added more selection to the Right-click menu associated with the LogFile text 
     76  field. 
     77 
    5778 
    58790.5.3b RC9 (06/30/2011) 
  • trunk/run.bat

    r323 r327  
    1 start javaw -Djava.library.path=lib/windows -Dawt.useSystemAAFontSettings=lcd -Dswing.aatext=true -Dsun.java2d.d3d=false -Xms642M -Xmx512M -jar RomRaider.jar 1>>romraider_sout.log 2>&1 
     1start javaw -Djava.library.path=lib/windows -Dawt.useSystemAAFontSettings=lcd -Dswing.aatext=true -Dsun.java2d.d3d=false -Xms64M -Xmx512M -jar RomRaider.jar 1>>romraider_sout.log 2>&1 
  • trunk/src/com/romraider/maps/Rom.java

    r282 r327  
    2424import com.romraider.swing.JProgressPane; 
    2525import com.romraider.xml.TableNotFoundException; 
     26import static com.romraider.maps.RomChecksum.calculateRomChecksum; 
     27import static com.romraider.util.HexUtil.asBytes; 
    2628import org.apache.log4j.Logger; 
    2729import javax.swing.JOptionPane; 
    2830import java.io.File; 
    2931import java.io.Serializable; 
     32import java.text.SimpleDateFormat; 
    3033import java.util.ArrayList; 
     34import java.util.Date; 
    3135import java.util.List; 
    3236import java.util.Vector; 
     
    180184 
    181185    public byte[] saveFile() { 
     186        Table checksum = null; 
    182187        for (Table table : tables) { 
    183188            table.saveFile(binData); 
     189            if (table.getName().equalsIgnoreCase("Checksum Fix")) 
     190                checksum = table; 
     191        } 
     192        if (checksum != null && !checksum.isLocked()) { 
     193                calculateRomChecksum(binData, checksum.getStorageAddress(), checksum.getDataSize()); 
     194        } 
     195        if (checksum != null) { 
     196                byte count = binData[checksum.getStorageAddress() + 207]; 
     197                if (count == -1) { 
     198                        count = 1; 
     199                } 
     200                else { 
     201                        count++; 
     202                } 
     203                String currentDate = new SimpleDateFormat("yyMMdd").format(new Date()); 
     204                String stamp = String.format("%s%02d", currentDate, count); 
     205                byte[] romStamp = asBytes(stamp); 
     206                System.arraycopy( 
     207                                romStamp, 
     208                                0, 
     209                                binData, 
     210                                checksum.getStorageAddress() + 204, 
     211                                4); 
    184212        } 
    185213        return binData; 
  • trunk/src/com/romraider/maps/Table.java

    r304 r327  
    10621062 
    10631063    public void applyColorSettings(Settings settings) { 
    1064         this.setSettings(settings); 
    1065  
    1066         // apply settings to cells 
    1067         for (int i = 0; i < getDataSize(); i++) { 
    1068             this.setMaxColor(settings.getMaxColor()); 
    1069             this.setMinColor(settings.getMinColor()); 
    1070             data[i].setHighlightColor(settings.getHighlightColor()); 
    1071             data[i].setIncreaseBorder(settings.getIncreaseBorder()); 
    1072             data[i].setDecreaseBorder(settings.getDecreaseBorder()); 
    1073             data[i].setFont(settings.getTableFont()); 
    1074             data[i].repaint(); 
    1075         } 
    1076         cellHeight = (int) settings.getCellSize().getHeight(); 
    1077         cellWidth = (int) settings.getCellSize().getWidth(); 
    1078         colorize(); 
    1079         validateScaling(); 
     1064        if (this.getType() != TABLE_SWITCH) { 
     1065                this.setSettings(settings); 
     1066         
     1067                // apply settings to cells 
     1068                for (int i = 0; i < getDataSize(); i++) { 
     1069                    this.setMaxColor(settings.getMaxColor()); 
     1070                    this.setMinColor(settings.getMinColor()); 
     1071                    data[i].setHighlightColor(settings.getHighlightColor()); 
     1072                    data[i].setIncreaseBorder(settings.getIncreaseBorder()); 
     1073                    data[i].setDecreaseBorder(settings.getDecreaseBorder()); 
     1074                    data[i].setFont(settings.getTableFont()); 
     1075                    data[i].repaint(); 
     1076                } 
     1077                cellHeight = (int) settings.getCellSize().getHeight(); 
     1078                cellWidth = (int) settings.getCellSize().getWidth(); 
     1079                colorize(); 
     1080                validateScaling(); 
     1081        } 
    10801082    } 
    10811083 
  • trunk/src/com/romraider/maps/TableSwitch.java

    r282 r327  
    11/* 
    2  * RomRaider Open-Source Tuning, Logging and Reflashing 
    3  * Copyright (C) 2006-2010 RomRaider.com 
    4  * 
    5  * This program is free software; you can redistribute it and/or modify 
    6  * it under the terms of the GNU General Public License as published by 
    7  * the Free Software Foundation; either version 2 of the License, or 
    8  * (at your option) any later version. 
    9  * 
    10  * This program is distributed in the hope that it will be useful, 
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    13  * GNU General Public License for more details. 
    14  * 
    15  * You should have received a copy of the GNU General Public License along 
    16  * with this program; if not, write to the Free Software Foundation, Inc., 
    17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
    18  */ 
    19  
     2* RomRaider Open-Source Tuning, Logging and Reflashing 
     3* Copyright (C) 2006-2010 RomRaider.com 
     4* 
     5* This program is free software; you can redistribute it and/or modify 
     6* it under the terms of the GNU General Public License as published by 
     7* the Free Software Foundation; either version 2 of the License, or 
     8* (at your option) any later version. 
     9* 
     10* This program is distributed in the hope that it will be useful, 
     11* but WITHOUT ANY WARRANTY; without even the implied warranty of 
     12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     13* GNU General Public License for more details. 
     14* 
     15* You should have received a copy of the GNU General Public License along 
     16* with this program; if not, write to the Free Software Foundation, Inc., 
     17* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
     18*/ 
     19  
    2020package com.romraider.maps; 
    21  
    22 import com.romraider.Settings; 
    23 import com.romraider.xml.RomAttributeParser; 
    24 import javax.swing.JCheckBox; 
    25 import javax.swing.JTextArea; 
     21  
     22import static javax.swing.JOptionPane.ERROR_MESSAGE; 
     23import static javax.swing.JOptionPane.WARNING_MESSAGE; 
     24import static javax.swing.JOptionPane.showMessageDialog; 
     25 
    2626import java.awt.BorderLayout; 
    2727import java.awt.Color; 
    2828import java.awt.Dimension; 
    29 import java.util.StringTokenizer; 
     29import java.awt.GridLayout; 
     30import java.awt.Insets; 
     31import java.util.Enumeration; 
     32import java.util.HashMap; 
     33import java.util.Map; 
     34 
     35import javax.swing.AbstractButton; 
     36import javax.swing.ButtonGroup; 
     37import javax.swing.JCheckBox; 
     38import javax.swing.JLabel; 
     39import javax.swing.JPanel; 
     40import javax.swing.JRadioButton; 
     41import javax.swing.JTextArea; 
     42 
     43import com.romraider.Settings; 
     44import static com.romraider.util.ByteUtil.indexOfBytes; 
     45import static com.romraider.util.HexUtil.asBytes; 
     46import static com.romraider.maps.RomChecksum.validateRomChecksum; 
    3047 
    3148public class TableSwitch extends Table { 
    32  
     49  
    3350    private static final long serialVersionUID = -4887718305447362308L; 
    34     private byte[] on = new byte[0]; 
    35     private byte[] off = new byte[0]; 
    3651    private JCheckBox checkbox = new JCheckBox("Enabled", true); // checkbox selected by default 
    37  
     52    private ButtonGroup buttonGroup = new ButtonGroup(); 
     53    private Map<String, byte[]> states = new HashMap<String, byte[]>(); 
     54    private int dataSize = 0; 
     55    private boolean isButtons = false; 
     56  
    3857    public TableSwitch(Settings settings) { 
    3958        super(settings); 
    4059        storageType = 1; 
    4160        type = TABLE_SWITCH; 
     61        locked = true; 
    4262        removeAll(); 
    4363        setLayout(new BorderLayout()); 
    4464    } 
    45  
     65  
    4666    public void setDataSize(int size) { 
    47         if (on.length == 0) { 
    48             on = new byte[size]; 
    49             off = new byte[size]; 
    50         } 
     67        if (dataSize == 0) dataSize = size; 
     68    } 
     69  
     70    public int getDataSize() { 
     71        return dataSize; 
    5172    } 
    5273 
    5374    public void populateTable(byte[] input) { 
    54         for (int i = 0; i < on.length; i++) { 
    55  
    56             // check each byte -- if it doesn't match "on", it's off 
    57             if (!beforeRam) { 
    58                 ramOffset = container.getRomID().getRamOffset(); 
    59             } 
    60  
    61             if (on[i] != input[storageAddress - ramOffset + i]) { 
     75        if (states.size() < 3) { 
     76            checkbox.setText("Enable " + name); 
     77            add(checkbox, BorderLayout.CENTER); 
     78        } 
     79        else { 
     80            isButtons = true; 
     81            JPanel radioPanel = new JPanel(new GridLayout(0, 1)); 
     82            radioPanel.add(new JLabel("  " + name)); 
     83            for (String stateName : states.keySet()) { 
     84                JRadioButton button = new JRadioButton(stateName); 
     85                buttonGroup.add(button); 
     86                radioPanel.add(button); 
     87            } 
     88            add(radioPanel, BorderLayout.CENTER); 
     89        } 
     90        
     91        // Validate the ROM image checksums. 
     92        // If the result is  1: any checksum failed 
     93        // if the result is  0: all the checksums matched 
     94        // if the result is -1: all the checksums have been previously disabled 
     95        if (super.getName().equalsIgnoreCase("Checksum Fix")) { 
     96                int result = validateRomChecksum(input, storageAddress, dataSize); 
     97                String message = String.format("One or more Checksums is invalid.%nThe ROM image may be corrupt.%nUse of this ROM image is not advised!"); 
     98                if (result == 1) { 
     99                showMessageDialog(this, 
     100                        message, 
     101                    "ERROR - Checksums Failed", 
     102                    ERROR_MESSAGE); 
     103                checkbox.setSelected(false); 
     104                checkbox.setEnabled(false); 
     105                } 
     106                else if (result == -1){ 
     107                        message = "All Checksums are disabled."; 
     108                showMessageDialog(this, 
     109                                message, 
     110                    "Warning - Checksum Status", 
     111                    WARNING_MESSAGE); 
     112                checkbox.setSelected(true); 
     113                checkbox.setEnabled(false); 
     114                } 
     115                else { 
     116                        locked = false; 
     117                } 
     118                return; 
     119        } 
     120 
     121        // Validate XML switch definition data against the ROM data to select 
     122        // the appropriate switch setting or throw an error if there is a 
     123        // mismatch and disable this table's editing ability. 
     124        if (!beforeRam) ramOffset = container.getRomID().getRamOffset(); 
     125        Map<String, Integer> sourceStatus = new HashMap<String, Integer>(); 
     126        for (String stateName : states.keySet()) { 
     127            byte[] sourceData = new byte[dataSize]; 
     128            System.arraycopy( 
     129                        input, 
     130                        storageAddress - ramOffset, 
     131                        sourceData, 
     132                        0, 
     133                        dataSize); 
     134            int compareResult = indexOfBytes(sourceData, getValues(stateName)); 
     135            if (compareResult == -1) { 
     136                if (isButtons) getButtonByText(buttonGroup, stateName).setSelected(false); 
    62137                checkbox.setSelected(false); 
     138            } 
     139            else { 
     140                if (isButtons) getButtonByText(buttonGroup, stateName).setSelected(true); 
     141                    checkbox.setSelected(true); 
     142            } 
     143            sourceStatus.put(stateName, compareResult); 
     144        } 
     145 
     146        for (String source : sourceStatus.keySet()) { 
     147            if (sourceStatus.get(source) != -1) { 
     148                locked = false; 
    63149                break; 
    64150            } 
    65151        } 
    66     } 
    67  
     152 
     153        if (locked) { 
     154                checkbox.setEnabled(false); 
     155                String mismatch = String.format("Table: %s%nTable editing has been disabled.%nDefinition file or ROM image may be corrupt.", super.getName()); 
     156                showMessageDialog(this, 
     157                                  mismatch, 
     158                                  "ERROR - Data Mismatch", 
     159                                  ERROR_MESSAGE); 
     160                if (isButtons) { 
     161                    for (String source : states.keySet()) 
     162                        setButtonUnselected(buttonGroup, source); 
     163                } 
     164        } 
     165    } 
     166  
    68167    public void setName(String name) { 
    69168        super.setName(name); 
    70         checkbox.setText("Enable " + name); 
    71  
    72         add(checkbox, BorderLayout.NORTH); 
    73     } 
    74  
     169    } 
     170  
    75171    public int getType() { 
    76172        return TABLE_SWITCH; 
    77173    } 
    78  
     174  
    79175    public void setDescription(String description) { 
    80176        super.setDescription(description); 
     
    84180        descriptionArea.setWrapStyleWord(true); 
    85181        descriptionArea.setLineWrap(true); 
    86  
    87         add(descriptionArea, BorderLayout.CENTER); 
    88     } 
    89  
     182        descriptionArea.setMargin(new Insets(0,5,5,5)); 
     183  
     184        add(descriptionArea, BorderLayout.SOUTH); 
     185    } 
     186  
    90187    public byte[] saveFile(byte[] input) { 
    91         if (checkbox.isSelected()) { // switch is on 
    92             for (int i = 0; i < on.length; i++) { 
    93                 input[storageAddress - ramOffset + i] = on[i]; 
    94             } 
    95  
    96         } else { // switch is off 
    97             for (int i = 0; i < on.length; i++) { 
    98                 input[storageAddress - ramOffset + i] = off[i]; 
    99             } 
    100         } 
     188        if (!super.getName().equalsIgnoreCase("Checksum Fix")) { 
     189                if (!locked) { 
     190                        if (isButtons) { 
     191                                JRadioButton button = getSelectedButton(buttonGroup); 
     192                                System.arraycopy( 
     193                                                states.get(button.getText()), 
     194                                                0, 
     195                                                input, 
     196                                                storageAddress - ramOffset, 
     197                                                dataSize); 
     198                        } 
     199                        else { 
     200                                if (checkbox.isSelected()) { // switch is on 
     201                                        System.arraycopy( 
     202                                                        getOnValues(), 
     203                                                        0, 
     204                                                        input, 
     205                                                        storageAddress - ramOffset, 
     206                                                        dataSize); 
     207                                } else if (!checkbox.isSelected()) { // switch is off 
     208                                        System.arraycopy( 
     209                                                        getOffValues(), 
     210                                                        0, 
     211                                                        input, 
     212                                                        storageAddress - ramOffset, 
     213                                                        dataSize); 
     214                                } 
     215                        } 
     216                } 
     217        } 
    101218        return input; 
    102219    } 
    103  
     220  
     221    public void setValues(String name, String input) { 
     222        states.put(name, asBytes(input)); 
     223    } 
     224  
    104225    public void setOnValues(String input) { 
    105         StringTokenizer tokens = new StringTokenizer(input); 
    106         for (int i = 0; i < off.length; i++) { 
    107             on[i] = (byte) RomAttributeParser.parseHexString(tokens.nextToken()); 
    108         } 
    109     } 
    110  
     226            setValues("on", input); 
     227    } 
     228  
    111229    public void setOffValues(String input) { 
    112         StringTokenizer tokens = new StringTokenizer(input); 
    113         for (int i = 0; i < off.length; i++) { 
    114             off[i] = (byte) RomAttributeParser.parseHexString(tokens.nextToken()); 
    115         } 
    116     } 
    117  
     230            setValues("off", input); 
     231    } 
     232  
     233    public byte[] getValues(String key) { 
     234            return states.get(key); 
     235    } 
     236  
    118237    public byte[] getOnValues() { 
    119         return on; 
    120     } 
    121  
     238            return states.get("on"); 
     239    } 
     240  
    122241    public byte[] getOffValues() { 
    123         return off; 
    124     } 
    125  
     242            return states.get("off"); 
     243    } 
     244  
    126245    public Dimension getFrameSize() { 
    127246        int height = verticalOverhead + 75; 
     
    136255        return new Dimension(width, height); 
    137256    } 
    138  
     257  
    139258    public void colorize() { 
    140259    } 
    141  
     260  
    142261    public void cursorUp() { 
    143262    } 
    144  
     263  
    145264    public void cursorDown() { 
    146265    } 
    147  
     266  
    148267    public void cursorLeft() { 
    149268    } 
    150  
     269  
    151270    public void cursorRight() { 
    152271    } 
    153  
     272  
    154273    public void setAxisColor(Color color) { 
    155274    } 
    156  
     275  
    157276    public boolean isLiveDataSupported() { 
    158277        return false; 
    159278    } 
     279  
     280    // returns the selected radio button in the specified group 
     281    private static JRadioButton getSelectedButton(ButtonGroup group) { 
     282        for (Enumeration<AbstractButton> e = group.getElements(); e.hasMoreElements(); ) { 
     283            JRadioButton b = (JRadioButton)e.nextElement(); 
     284            if (b.getModel() == group.getSelection()) { 
     285                return b; 
     286            } 
     287        } 
     288        return null; 
     289    } 
     290  
     291    // Unselects & disables all radio buttons in the specified group 
     292    private static void setButtonUnselected(ButtonGroup group, String text) { 
     293        for (Enumeration<AbstractButton> e = group.getElements(); e.hasMoreElements(); ) { 
     294            JRadioButton b = (JRadioButton)e.nextElement(); 
     295            b.setSelected(false); 
     296            b.setEnabled(false); 
     297        } 
     298    } 
     299  
     300    // returns the radio button based on its display text 
     301    private static JRadioButton getButtonByText(ButtonGroup group, String text) { 
     302        for (Enumeration<AbstractButton> e = group.getElements(); e.hasMoreElements(); ) { 
     303            JRadioButton b = (JRadioButton)e.nextElement(); 
     304            if (b.getText().equalsIgnoreCase(text)) { 
     305                return b; 
     306            } 
     307        } 
     308        return null; 
     309    } 
    160310} 
  • trunk/src/com/romraider/swing/RomTree.java

    r282 r327  
    5252 
    5353    public void mouseClicked(MouseEvent e) { 
     54        showHideTable(e); 
     55    } 
    5456 
    55         try { 
     57    private void showHideTable(MouseEvent e) { 
     58    try { 
    5659 
    5760            Object selectedRow = getPathForLocation(e.getX(), e.getY()).getLastPathComponent(); 
  • trunk/src/com/romraider/swing/TablePropertyPanel.java

    r306 r327  
    197197        lblStorageAddress.setFocusable(false); 
    198198 
    199         lblStorageSize.setText("Storage Size:"); 
     199        lblStorageSize.setText("Data Type:"); 
    200200        lblStorageSize.setFocusable(false); 
    201201 
  • trunk/src/com/romraider/util/ByteUtil.java

    r326 r327  
    6060                } 
    6161        } 
     62 
     63    public static int indexOfBytes(byte[] bytes, byte[] pattern) { 
     64        int[] failure = computeFailure(pattern); 
     65        int j = 0; 
     66        for (int i = 0; i < bytes.length; i++) { 
     67            while (j > 0 && pattern[j] != bytes[i]) { 
     68                j = failure[j - 1]; 
     69            } 
     70            if (pattern[j] == bytes[i]) { 
     71                j++; 
     72            } 
     73            if (j == pattern.length) { 
     74                return i - pattern.length + 1; 
     75            } 
     76        } 
     77        return -1; 
     78    } 
     79 
     80    private static int[] computeFailure(byte[] pattern) { 
     81        int[] failure = new int[pattern.length]; 
     82        int j = 0; 
     83        for (int i = 1; i < pattern.length; i++) { 
     84            while (j>0 && pattern[j] != pattern[i]) { 
     85                j = failure[j - 1]; 
     86            } 
     87            if (pattern[j] == pattern[i]) { 
     88                j++; 
     89            } 
     90            failure[i] = j; 
     91        } 
     92        return failure; 
     93    } 
    6294} 
  • trunk/src/com/romraider/xml/DOMRomUnmarshaller.java

    r306 r327  
    470470 
    471471                } else if (n.getNodeName().equalsIgnoreCase("state")) { 
    472                     // set on/off values for switch type 
    473472                    if (unmarshallAttribute(n, "name", "").equalsIgnoreCase("on")) { 
    474473                        ((TableSwitch) table).setOnValues(unmarshallAttribute(n, "data", "0")); 
     
    477476                        ((TableSwitch) table).setOffValues(unmarshallAttribute(n, "data", "0")); 
    478477 
    479                     } 
     478                    } else ((TableSwitch) table).setValues(unmarshallAttribute(n, "name", ""), unmarshallAttribute(n, "data", "0")); 
    480479 
    481480                } else { /*unexpected element in Table (skip) */ } 
  • trunk/version.properties

    r325 r327  
    2424version.buildnumber=${buildnumber} 
    2525version.extra=Beta 
    26 version.extra1=RC9 
     26version.extra1=RC10 
    2727 
    2828# the starting class for the application 
Note: See TracChangeset for help on using the changeset viewer.