public void modelOpen()
        {
            string path = textBox1.Text;
            EndianBinaryReader readModel = new EndianBinaryReader(File.OpenRead(path), Endianness.LittleEndian);
            nsbmd = new NSBMD_File();
            if (readModel.ReadString(Encoding.ASCII, 4) != "BMD0")
            {
                readModel.Close();
                return;
            }
            else
            {
                nsbmd.Header.ID = "BMD0";
                nsbmd.Header.Magic = readModel.ReadBytes(4);
                nsbmd.Header.file_size = readModel.ReadInt32();
                nsbmd.Header.header_size = readModel.ReadInt16();
                nsbmd.Header.nSection = readModel.ReadInt16();
                nsbmd.Header.Section_Offset = new Int32[nsbmd.Header.nSection];
                for (int i = 0; i < nsbmd.Header.nSection; i++)
                {
                    nsbmd.Header.Section_Offset[i] = readModel.ReadInt32();
                }
                nsbmd.MDL0.ID = readModel.ReadString(Encoding.ASCII, 4);
                if (nsbmd.MDL0.ID != "MDL0")
                {
                    readModel.Close();
                    return;
                }

                nsbmd.MDL0.Section_size = readModel.ReadInt32();
                nsbmd.MDL0.Padding1 = readModel.ReadByte();
                nsbmd.MDL0.Model_count = readModel.ReadByte();
                nsbmd.MDL0.Section_size = readModel.ReadInt16();
                nsbmd.MDL0.Constant = readModel.ReadInt16();
                nsbmd.MDL0.Subsection_size = readModel.ReadInt16();
                nsbmd.MDL0.Constant2 = readModel.ReadInt32();
                nsbmd.MDL0.Unknown = new int[nsbmd.MDL0.Model_count];
                for (int i = 0; i < nsbmd.MDL0.Model_count; i++)
                {
                    nsbmd.MDL0.Unknown[i] = readModel.ReadInt32();
                }
                nsbmd.MDL0.Constant3 = readModel.ReadInt16();
                nsbmd.MDL0.Section2_size = readModel.ReadInt16();
                nsbmd.MDL0.Model_offset = new int[nsbmd.MDL0.Model_count];
                for (int i = 0; i < nsbmd.MDL0.Model_count; i++)
                {
                    nsbmd.MDL0.Model_offset[i] = readModel.ReadInt32();
                }
                nsbmd.MDL0.Model_name = new string[nsbmd.MDL0.Model_count];
                for (int i = 0; i < nsbmd.MDL0.Model_count; i++)
                {
                    nsbmd.MDL0.Model_name[i] = readModel.ReadString(Encoding.ASCII, 16);
                }
                readModel.Close();
            }
        }
Exemple #2
0
 // Public Methods (2)
 /// <summary>
 /// Load NSBTX from stream.
 /// </summary>
 /// <param name="stream">Stream to use.</param>
 /// <returns>Material definitions.</returns>
 public static IEnumerable<NsbmdAnimation> LoadNsbca(Stream stream)
 {
     List<NsbmdAnimation> animation = new List<NsbmdAnimation>();
     var reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
     byte[] id = reader.ReadBytes(4);
     if (id == new byte[] { 0x42, 0x43, 0x41, 0x30 })
     {
         throw new Exception();
     }
     int i = reader.ReadInt32();
     if (i == Nsbmd.NDS_TYPE_MAGIC1)
     {
         i = reader.ReadInt32();
         if (i == stream.Length)
         {
             int numblock = reader.ReadInt32();
             numblock >>= 16;
             int r = reader.ReadInt32();
             id = reader.ReadBytes(4);
             if (numblock == 1 && r == 0x14)
             {
                 animation.AddRange(ReadJnt0(stream, 0x14));
             }
         }
     }
     reader.Close();
     return animation;
 }
Exemple #3
0
 public override void ToXml(XmlDocument yaml, XmlNode node, List<string> nodes, List<string> values, List<byte[]> data)
 {
     XmlAttribute attr = yaml.CreateAttribute("type");
     attr.Value = "path";
     node.Attributes.Append(attr);
     using (EndianBinaryReader rd = new EndianBinaryReader(new MemoryStream(data[Value])))
     {
         while (rd.BaseStream.Position != rd.BaseStream.Length)
         {
             XmlElement point = yaml.CreateElement("point");
             point.SetAttribute("x", rd.ReadSingle().ToString(CultureInfo.InvariantCulture) + "f");
             point.SetAttribute("y", rd.ReadSingle().ToString(CultureInfo.InvariantCulture) + "f");
             point.SetAttribute("z", rd.ReadSingle().ToString(CultureInfo.InvariantCulture) + "f");
             point.SetAttribute("nx", rd.ReadSingle().ToString(CultureInfo.InvariantCulture) + "f");
             point.SetAttribute("ny", rd.ReadSingle().ToString(CultureInfo.InvariantCulture) + "f");
             point.SetAttribute("nz", rd.ReadSingle().ToString(CultureInfo.InvariantCulture) + "f");
             point.SetAttribute("val", rd.ReadInt32().ToString(CultureInfo.InvariantCulture));
             node.AppendChild(point);
         }
         rd.Close();
     }
 }
Exemple #4
0
        private static void ConvertPath(string path)
        {
            using (var reader = new EndianBinaryReader(new FileStream(path, FileMode.Open)))
            {
                string outpath;
                bool toyaml;

                if (reader.ReadString(Encoding.ASCII, 2) == "BY")
                {
                    toyaml = true;
                    outpath = Path.ChangeExtension(path, "xml");
                    if (outpath == path)
                        outpath = path + ".xml";
                }
                else
                {
                    toyaml = false;
                    outpath = Path.ChangeExtension(path, "byaml");
                    if (outpath == path)
                        outpath = path + ".byaml";
                }

                reader.BaseStream.Seek(0, SeekOrigin.Begin);

                if (toyaml)
                {
                    ConvertFromByaml(reader, outpath);
                }
                else
                {
                    ConvertToByaml(reader, outpath);
                }

                reader.Close();
            }
        }
Exemple #5
0
        /// <summary>
        /// genAIS command.  Always use section-by-section CRC checks
        /// </summary>
        /// <param name="coffFileName"></param>
        /// <param name="bootMode"></param>
        /// <returns>Bytes of the binary or text AIS command</returns>
        public static Byte[] GenAIS(String coffFileName,
                                AISGen devAISGen, 
                                INISection[] iniSecs)
        {
            UInt32 busWidth = 8;
              UInt32 addrWidth = 16;
              UInt32 numTargetSections = 0;
              UInt32 numWords;
              UInt32 entryPoint = 0x00000000;
              Boolean seqReadEn = false;     // Not supported on all devices
              String finalFxnName = null;    // Not supported in all devices

              Hashtable UARTSendDONE_DataSection=null, UARTSendDONE_TextSection=null;

              // Lists to keep track of the input object and binary files
              List<ObjectFile> objectFiles = new List<ObjectFile>();
              List<BinaryFile> binaryFiles = new List<BinaryFile>();

              // COFF file objects for the main application and the AIS extras executable
              COFFFile AISExtrasCF=null;

              // Set defaults
              devAISGen.finalFxnName              = null;
              // List to keep track of loadable sections and their occupied memory ranges
              devAISGen.sectionMemory = new List<MemoryRange>();

              // Setup the binary writer to generate the temp AIS file
              devAISGen.devAISStream              = new MemoryStream();
              EndianBinaryWriter tempAIS_bw       = new EndianBinaryWriter( devAISGen.devAISStream, devAISGen.devEndian);

              #region INI Data parsing
              // Get data from the GENERAL INI Section
              for (UInt32 i = 0; i < iniSecs.Length; i++)
              {
            INISection sec = iniSecs[i];
            if (sec.iniSectionName.Equals("GENERAL", StringComparison.OrdinalIgnoreCase))
            {
              foreach (DictionaryEntry de in sec.sectionValues)
              {
            // Read buswidth
            if (((String)de.Key).Equals("BUSWIDTH", StringComparison.OrdinalIgnoreCase))
              busWidth = (UInt32)sec.sectionValues["BUSWIDTH"];

            // Read BootMode (unless already set)
            if ((((String)de.Key).Equals("BOOTMODE", StringComparison.OrdinalIgnoreCase)) && (devAISGen.bootMode == BootModes.NONE))
              devAISGen.bootMode = (BootModes) Enum.Parse(typeof(BootModes), (String)sec.sectionValues["BOOTMODE"], true);

            // Read Addr width (for I2C/SPI)
            if (((String)de.Key).Equals("ADDRWIDTH", StringComparison.OrdinalIgnoreCase))
              addrWidth = (UInt32)sec.sectionValues["ADDRWIDTH"];

            // Sequential Read ENABLE
            if (((String)de.Key).Equals("SEQREADEN", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["SEQREADEN"]).Equals("ON", StringComparison.OrdinalIgnoreCase))
                seqReadEn = true;
              if (((String)sec.sectionValues["SEQREADEN"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                seqReadEn = true;
            }

            // CRC Type override
            if (((String)de.Key).Equals("CRCCHECKTYPE", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.CRCType = (CRCCheckType) Enum.Parse(typeof(CRCCheckType), (String)sec.sectionValues["CRCCHECKTYPE"], true);
            }

            // Finalize fxn symbol name
            if (((String)de.Key).Equals("FINALFXNSYMBOLNAME", StringComparison.OrdinalIgnoreCase))
            {
              finalFxnName = (String)sec.sectionValues["FINALFXNSYMBOLNAME"];
            }

            // Read entrypoint value
            if (((String)de.Key).Equals("ENTRYPOINT", StringComparison.OrdinalIgnoreCase))
              entryPoint = (UInt32)sec.sectionValues["ENTRYPOINT"];
              }
            }

            if (sec.iniSectionName.Equals("BINARYINPUTFILE", StringComparison.OrdinalIgnoreCase))
            {
              BinaryFile currFile = new BinaryFile();
              currFile.fileName = null;
              currFile.useEntryPoint = false;
              currFile.loadAddr = 0x00000000;
              currFile.entryPointAddr = 0x00000000;

              foreach (DictionaryEntry de in sec.sectionValues)
              {

            // File name for binary section data
            if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
            {
               currFile.fileName = (String) sec.sectionValues["FILENAME"];
            }

            // Binary section's load address in the memory map
            if (((String)de.Key).Equals("LOADADDRESS", StringComparison.OrdinalIgnoreCase))
            {
              currFile.loadAddr = (UInt32) sec.sectionValues["LOADADDRESS"];
            }

            // Binary section's entry point address in the memory map
            if (((String)de.Key).Equals("ENTRYPOINTADDRESS", StringComparison.OrdinalIgnoreCase))
            {
              currFile.entryPointAddr = (UInt32) sec.sectionValues["ENTRYPOINTADDRESS"];
            }

            // Option to specify that this entry point should be used for AIS
            if (((String)de.Key).Equals("USEENTRYPOINT", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
            }
              }

              if (currFile.fileName == null)
              {
            Console.WriteLine("ERROR: File name must be provided for binary input file.");
            return null;
              }

              if (currFile.loadAddr == 0x00000000)
              {
            Console.WriteLine("ERROR: Valid load address must be provided for binary input file.");
            return null;
              }

              binaryFiles.Add(currFile);
            }

            if (sec.iniSectionName.Equals("OBJECTINPUTFILE", StringComparison.OrdinalIgnoreCase))
            {
              ObjectFile currFile = new ObjectFile();
              currFile.useEntryPoint = false;
              currFile.fileName = null;

              foreach (DictionaryEntry de in sec.sectionValues)
              {
            // File name for binary section data
            if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
            {
               currFile.fileName = (String) sec.sectionValues["FILENAME"];
            }

            // Option to specify that this entry point should be used for AIS
            if (((String)de.Key).Equals("USEENTRYPOINT", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
            }
              }

              if (currFile.fileName == null)
              {
            Console.WriteLine("ERROR: File name must be provided for input object file.");
            return null;
              }

              objectFiles.Add(currFile);
            }
              }

              #endregion

              #region AIS Generation
              // ---------------------------------------------------------
              // ****************** BEGIN AIS GENERATION *****************
              // ---------------------------------------------------------
              Console.WriteLine("Begining the AIS file generation.");

              // Diaplay currently selected boot mode
              Console.WriteLine("AIS file being generated for bootmode: {0}.",Enum.GetName(typeof(BootModes),devAISGen.bootMode));

              #region AIS Extras and UARTSendDONE Setup
              //Create the COFF file object for the AISExtras file (if it exists/is defined)
              if (devAISGen.AISExtraFileName != null)
              {
            EmbeddedFileIO.ExtractFile(Assembly.GetExecutingAssembly(), devAISGen.AISExtraFileName, false);

            if (File.Exists(devAISGen.AISExtraFileName))
            {
              // The file exists, so use it
              AISExtrasCF = new COFFFile(devAISGen.AISExtraFileName);
            }
            else
            {
              throw new FileNotFoundException("The AISExtra file, " + devAISGen.AISExtraFileName + ", was not found.");
            }
              }

              // If we have the AISExtras COFF file object, use it to setup the addresses
              // for the AISExtra functions.  These will utilize the L1P and L1D spaces that
              // are usually cache.
              if ( (AISExtrasCF != null) && (devAISGen.AISExtraFunc != null))
              {
            // Use symbols to get address for AISExtra functions and parameters
            for (Int32 i = 0; i < devAISGen.AISExtraFunc.Length; i++)
            {
              Hashtable sym = AISExtrasCF.symFind("_" + devAISGen.AISExtraFunc[i].funcName);
              devAISGen.AISExtraFunc[i].funcAddr = (UInt32)sym["value"];
              sym = AISExtrasCF.symFind(".params");
              devAISGen.AISExtraFunc[i].paramAddr = (UInt32)sym["value"];
            }

            // If the bootMode is UART we need the UARTSendDONE function
            if (devAISGen.bootMode == BootModes.UART)
            {
              // Set address for the UARTSendDone Function in the .text:uart section
              UARTSendDONE_TextSection = AISExtrasCF.secFind(".text:uart");
              UARTSendDONE_DataSection = AISExtrasCF.secFind(".data:uart");

              // Eliminate these as loadable since they will be loaded first, separate
              // from the main COFF file
              UARTSendDONE_TextSection["copyToTarget"] = false;
              UARTSendDONE_DataSection["copyToTarget"] = false;
              AISExtrasCF.Header["numTargetSections"] = ((UInt32)AISExtrasCF.Header["numTargetSections"] - (UInt32)2);

              // Set the actual run address for the UARTSendDONE function
              if ((UARTSendDONE_TextSection != null) && (UARTSendDONE_DataSection != null))
              {
            Debug.DebugMSG("UART section found");
            devAISGen.UARTSendDONEAddr = (UInt32)UARTSendDONE_TextSection["phyAddr"];
            Hashtable sym = AISExtrasCF.symFind("_UARTSendDONE");
            if (sym != null)
            {
              devAISGen.UARTSendDONEAddr = (UInt32)sym["value"];
              Debug.DebugMSG("UARTSendDONE at 0x{0:X8}",devAISGen.UARTSendDONEAddr);
            }
              }
              else
              {
            Console.WriteLine("UARTSendDONE function not found in AISExtra COFF file!!!");
            return null;
              }
            }
              }

              // Setup boolean indicating whether to include UARTSendDONE jump commands
              if ((devAISGen.bootMode == BootModes.UART) && (devAISGen.UARTSendDONEAddr != 0x0))
            devAISGen.SendUARTSendDONE = true;
              else
            devAISGen.SendUARTSendDONE = false;

              #endregion

              #region Write AIS MAGIC Number and initial data
              // Write the premilinary header and fields (everything before first AIS command)
              switch (devAISGen.bootMode)
              {
            case BootModes.EMIFA:
            {
              if (busWidth == 16)
            tempAIS_bw.Write((UInt32)(0x1 << 0)|(0x2 << 4));
              else
            tempAIS_bw.Write((UInt32)(0x0 << 0)|(0x2 << 4));
              tempAIS_bw.Write((UInt32)AIS.MagicNumber);
              break;
            }
            case BootModes.NAND:
            {
              tempAIS_bw.Write((UInt32)AIS.MagicNumber);
              tempAIS_bw.Write((UInt32)0);
              tempAIS_bw.Write((UInt32)0);
              tempAIS_bw.Write((UInt32)0);
              break;
            }
            case BootModes.UART:
            {
              tempAIS_bw.Write((UInt32)AIS.MagicNumber);
              break;
            }
            case BootModes.I2CMASTER:
            {
              if (addrWidth == 16)
            tempAIS_bw.Write((UInt32)2);
              else
            tempAIS_bw.Write((UInt32)1);
              tempAIS_bw.Write((UInt32)AIS.MagicNumber);
              break;
            }
            case BootModes.SPIMASTER:
            {
              if (addrWidth == 24)
            tempAIS_bw.Write((UInt32)3);
              else if (addrWidth == 16)
            tempAIS_bw.Write((UInt32)2);
              else
            tempAIS_bw.Write((UInt32)1);
              tempAIS_bw.Write((UInt32)AIS.MagicNumber);
              break;
            }
            default:
            {
              tempAIS_bw.Write((UInt32)AIS.MagicNumber);
              break;
            }
              };
              #endregion

              #region Send UARTSendDONE sections
              //Send UART code if it exists
              if (devAISGen.SendUARTSendDONE)
              {
            CRCCheckType tempCRCType = devAISGen.crcType;
            devAISGen.crcType = CRCCheckType.NO_CRC;
            devAISGen.SendUARTSendDONE = false;
            AISSectionLoad(AISExtrasCF, UARTSendDONE_TextSection, devAISGen);
            AISSectionLoad(AISExtrasCF, UARTSendDONE_DataSection, devAISGen);
            devAISGen.SendUARTSendDONE = true;
            devAISGen.crcType = tempCRCType;
              }
              #endregion

              #region ROM Function insertion

              // Insert words for ROM function execution
              for (UInt32 i = 0; i < devAISGen.ROMFunc.Length; i++)
              {
            for (UInt32 j = 0; j < iniSecs.Length; j++)
            {
              if (iniSecs[j].iniSectionName.Equals(devAISGen.ROMFunc[i].iniSectionName))
              {
            UInt32 funcIndex = i;

            tempAIS_bw.Write((UInt32)AIS.FunctionExec);
            tempAIS_bw.Write((((UInt32)devAISGen.ROMFunc[i].numParams) << 16) + ((UInt32)funcIndex));
            // Write Paramter values read from INI file
            for (Int32 k = 0; k < devAISGen.ROMFunc[i].numParams; k++)
            {
              //FIXME
              Debug.DebugMSG("\tParam name: {0}, Param num: {1}, Value: {2}\n",
                devAISGen.ROMFunc[i].paramNames[k],
                k,
                iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToUpper()]);
              tempAIS_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToUpper()]);
            }
            // Call UARTSendDONE from AIS Extras if this is for UART boot
            if (devAISGen.SendUARTSendDONE)
            {
              tempAIS_bw.Write((UInt32)AIS.Jump);
              tempAIS_bw.Write(devAISGen.UARTSendDONEAddr);
            }
              }
            }
              }

              #endregion

              #region Insert seqread command
              if (seqReadEn == true)
            tempAIS_bw.Write((UInt32)AIS.SeqReadEnable);

              #endregion

              #region AIS executable data download
              if (AISExtrasCF != null)
              {
              // Load the AISExtras COFF file
              AISCOFFLoad(AISExtrasCF, devAISGen);
              }
              #endregion

              #region AIS Extras init function execution
              //Insert calls for any AISExtra Init functions (like power domains)
              if (AISExtrasCF != null)
              {
            for (UInt32 i = 0; i < devAISGen.AISExtraFunc.Length; i++)
            {
              if (devAISGen.AISExtraFunc[i].isInitFunc)
              {
            for (UInt32 j = 0; j < iniSecs.Length; j++)
            {
              if (iniSecs[j].iniSectionName.Equals(devAISGen.AISExtraFunc[i].iniSectionName))
              {
                for (UInt32 k = 0; k < devAISGen.AISExtraFunc[i].numParams; k++)
                {
                  // Write SET command
                  tempAIS_bw.Write((UInt32)AIS.Set);
                  //Write type field (32-bit only)
                  tempAIS_bw.Write((UInt32)0x3);
                  // Write appropriate parameter address
                  tempAIS_bw.Write((UInt32) (devAISGen.AISExtraFunc[i].paramAddr + (k * 4)));
                  //Write data to write
                  tempAIS_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.AISExtraFunc[i].paramNames[k].ToString()]);
                  //Write Sleep value (should always be zero)
                  //tempAIS_bw.Write((UInt32)0x1000);
                  tempAIS_bw.Write((UInt32)0x0);
                }

                // Now that params are set, Jump to function
                tempAIS_bw.Write((UInt32)AIS.Jump);
                tempAIS_bw.Write(devAISGen.AISExtraFunc[i].funcAddr);

                // Call UARTSendDONE from AIS Extras if this is for UART boot
                if (devAISGen.SendUARTSendDONE)
                {
                  tempAIS_bw.Write((UInt32)AIS.Jump);
                  tempAIS_bw.Write(devAISGen.UARTSendDONEAddr);
                }
              }
            }
              }
            }
              }
              #endregion

              Debug.DebugMSG("Starting binary file section loads.");

              #region Insert binary data files as SECTION_LOAD commands
              // Insert binary files
              for (Int32 i=0; i<binaryFiles.Count; i++)
              {
            if (File.Exists(binaryFiles[i].fileName))
            {

              AISBinarySectionLoad(binaryFiles[i].fileName, devAISGen, binaryFiles[i].loadAddr);
              Debug.DebugMSG("Binary file {0} found.", binaryFiles[i].fileName);

              numTargetSections++;

              if (binaryFiles[i].useEntryPoint)
              {
            entryPoint = binaryFiles[i].entryPointAddr;
              }
            }
            else
            {
              Console.WriteLine("WARNING: Binary input file {0} was not found. Skipping.",binaryFiles[i].fileName);
            }
              }
              #endregion

              Debug.DebugMSG("Starting object file section loads.");

              #region COFF file parsing and loading
              // Create the COFF file object for the main application being loaded (if it exists)
              if (File.Exists(coffFileName))
              {
            ObjectFile currFile = new ObjectFile();
            currFile.useEntryPoint = true;
            currFile.fileName = coffFileName;

            // Cycle throught all other object files loaded via INI file and unset their
            // useEntryPoint boolean, warning us as we do
            Boolean showWarning = false;
            for (Int32 i=0; i<objectFiles.Count; i++)
            {
              // Insert binary file
              if (objectFiles[i].useEntryPoint)
              {
            objectFiles[i].useEntryPoint = false;
            showWarning = true;
              }
            }

            if (showWarning)
              Console.WriteLine("WARNING: Ignoring useEntryPoint flag from all object file sections of INI file");

            objectFiles.Add(currFile);
              }

              // Insert object files
              for (Int32 i=0; i<objectFiles.Count; i++)
              {
            if (File.Exists(objectFiles[i].fileName))
            {
              // FIXME: Add support to detect ELF or COFF and support ELF parsing

              // Parse the object file
              COFFFile cf = new COFFFile(objectFiles[i].fileName);

              if (cf != null)
              {
            // Load the object file contents
            AISCOFFLoad(cf, devAISGen);
              }
              else
              {
            Console.WriteLine("ERROR: Parsing the input object file {0} failed!",objectFiles[i].fileName);
              }

              // If entry point is still null, use the coff file one
              if (entryPoint == 0x00000000)
              {
            if (objectFiles[i].useEntryPoint)
            {
              entryPoint = (UInt32)cf.Header["optEntryPoint"];
            }
              }

              // Insert final function register function
              if (devAISGen.finalFxnName != null)
              {
            Hashtable symbol;
            // Look for the symbol in the Coff file symbols table
            symbol = cf.symFind(devAISGen.finalFxnName);

            // If found, insert the command
            if (symbol != null)
            {
              tempAIS_bw.Write((UInt32)AIS.FinalFxnReg);
              tempAIS_bw.Write((UInt32)symbol["value"]);

              Console.WriteLine("Finalize function symbol, '{0}', found as address 0x{1:X8}.",devAISGen.finalFxnName,(UInt32)symbol["value"]);
            }
            else
            {
              Console.WriteLine("Finalize function symbol, '{0}', not found.",devAISGen.finalFxnName);
            }
              }

              // Close object file
              if (cf != null)
            cf.Close();
            }
            else
            {
              Console.WriteLine("WARNING: Input object file {0} was not found. Skipping.",objectFiles[i].fileName);
            }
              }

              #endregion

              #region Insert Final JUMP_CLOSE command
              tempAIS_bw.Write((UInt32)AIS.Jump_Close);
              tempAIS_bw.Write(entryPoint);

              if (entryPoint == 0x00000000)
            Console.WriteLine("WARNING: Entry point never set or set to invalid value");

              // Flush the data and then return to start
              devAISGen.devAISStream.Flush();
              devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);
              #endregion

              // Console output
              Console.WriteLine("AIS file generation was successful.");

              // ---------------------------------------------------------
              // ******************* END AIS GENERATION ******************
              // ---------------------------------------------------------
              #endregion

              #region Prepare the return byte array
              // Now create return Byte array based on tempAIS file and the bootmode
              EndianBinaryReader tempAIS_br;
              tempAIS_br = new EndianBinaryReader(
              devAISGen.devAISStream,
              Endian.LittleEndian);

              // Setup the binary reader object
              numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
              devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes

              Debug.DebugMSG("Number of words in the stream is {0}", numWords);

              // Copy the data to the output Byte array
              for (UInt32 i = 0; i < numWords; i++)
              {
            BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
              }

              // Close the binary reader
              tempAIS_br.Close();

              // Close the COFF files since we are done with them
              if (AISExtrasCF != null)
              {
            AISExtrasCF.Close();
              }

              // Clean up any embedded file resources that may have been extracted
              EmbeddedFileIO.CleanUpEmbeddedFiles();

              #endregion

              // Return Byte Array
              return devAISGen.AISData;
        }
Exemple #6
0
        /// <summary>
        /// genAIS command.  Always use section-by-section CRC checks
        /// </summary>
        /// <param name="coffFileName"></param>
        /// <param name="bootMode"></param>
        /// <returns>Bytes of the binary or text AIS command</returns>
        public static Byte[] GenAIS(String coffFileName,
            AISGen devAISGen)
        {
            UInt32 busWidth = 8;
            UInt32 numTargetSections;
            //UInt32 totalLoadableSize = 0;
            UInt32 numWords;
            Hashtable UARTSendDONE_DataSection=null, UARTSendDONE_TextSection=null;

            // COFF file objects for the main application and the AIS extras executable
            COFFFile cf=null, AISExtrasCF=null;

            // ---------------------------------------------------------
            // ****************** BEGIN AIS GENERATION *****************
            // ---------------------------------------------------------
            Console.WriteLine("Begining the AIS file generation.");

            #region AIS Generation

            // Setup the binary writer to generate the temp AIS file
            devAISGen.devAISFileStream =  new FileStream( devAISGen.devAISFileName,
                                                          FileMode.Create,
                                                          FileAccess.Write);
            EndianBinaryWriter tempAIS_bw = new EndianBinaryWriter(
                                                          devAISGen.devAISFileStream,
                                                          devAISGen.devEndian);

            #region INI File parsing
            // Parse the INI file (describes details for initializing the device)
            // using AIS ROM functions and possibly AISExtras functions)
            INISection[] iniSecs = AISGen.iniParse(devAISGen.devINIFileName);

            // Get data from the GENERAL INI Section
            for (UInt32 i = 0; i < iniSecs.Length; i++)
            {
                INISection sec = iniSecs[i];
                if (sec.iniSectionName.Equals("GENERAL", StringComparison.OrdinalIgnoreCase))
                {
                    foreach (DictionaryEntry de in sec.sectionValues)
                    {
                        // Read AEMIF buswidth
                        if (((String)de.Key).Equals("BUSWIDTH"))
                            busWidth = (UInt32)sec.sectionValues["BUSWIDTH"];
                        // Read BootMode (unless already set)
                        if ((((String)de.Key).Equals("BOOTMODE")) && (devAISGen.bootMode == BootModes.NONE))
                             devAISGen.bootMode = (BootModes) Enum.Parse(typeof(BootModes), (String)sec.sectionValues["BOOTMODE"], true);
                    }
                }
            }

            // Check to make sure some bootmode has been set, if not make a default
            if (devAISGen.bootMode == BootModes.NONE)
            {
                devAISGen.bootMode = BootModes.EMIFA;
            }
            Console.WriteLine("AIS file being generated for the {0} bootmode.",Enum.GetName(typeof(BootModes),devAISGen.bootMode));
            #endregion

            #region AIS Extras and UARTSendDONE Setup
            //Create the COFF file object for the AISExtras file (if it exists/is defined)
            if (devAISGen.AISExtraFileName != null)
            {
                EmbeddedFileIO.ExtractFile(Assembly.GetExecutingAssembly(), devAISGen.AISExtraFileName, false);

                if (File.Exists(devAISGen.AISExtraFileName))
                {
                    // The file exists, so use it
                    AISExtrasCF = new COFFFile(devAISGen.AISExtraFileName);
                }
                else
                {
                    throw new FileNotFoundException("The AISExtra file, " + devAISGen.AISExtraFileName + ", was not found.");
                }
            }

            // If we have the AISExtras COFF file object, use it to setup the addresses
            // for the AISExtra functions.  These will utilize the L1P and L1D spaces that
            // are usually cache.
            if (AISExtrasCF != null)
            {
                // Use symbols to get address for AISExtra functions and parameters
                for (Int32 i = 0; i < devAISGen.AISExtraFunc.Length; i++)
                {
                    Hashtable sym = AISExtrasCF.symFind("_" + devAISGen.AISExtraFunc[i].funcName);
                    devAISGen.AISExtraFunc[i].funcAddr = (UInt32)sym["value"];
                    sym = AISExtrasCF.symFind(".params");
                    devAISGen.AISExtraFunc[i].paramAddr = (UInt32)sym["value"];
                }

                // If the bootMode is UART we need the UARTSendDONE function
                if (devAISGen.bootMode == BootModes.UART)
                {
                    // Set address for the UARTSendDone Function in the .text:uart section
                    UARTSendDONE_TextSection = AISExtrasCF.secFind(".text:uart");
                    UARTSendDONE_DataSection = AISExtrasCF.secFind(".data:uart");

                    // Eliminate these as loadable since they will be loaded first, separate
                    // from the main COFF file
                    UARTSendDONE_TextSection["copyToTarget"] = false;
                    UARTSendDONE_DataSection["copyToTarget"] = false;
                    AISExtrasCF.Header["numTargetSections"] = ((UInt32)AISExtrasCF.Header["numTargetSections"] - (UInt32)2);

                    // Set the actual run address for the UARTSendDONE function
                    if ((UARTSendDONE_TextSection != null) && (UARTSendDONE_DataSection != null))
                    {
                        Debug.DebugMSG("UART section found");
                        devAISGen.UARTSendDONEAddr = (UInt32)UARTSendDONE_TextSection["phyAddr"];
                        Hashtable sym = AISExtrasCF.symFind("_UARTSendDONE");
                        if (sym != null)
                        {
                            devAISGen.UARTSendDONEAddr = (UInt32)sym["value"];
                            Debug.DebugMSG("UARTSendDONE at 0x{0:X8}",devAISGen.UARTSendDONEAddr);
                        }
                    }
                    else
                    {
                        Console.WriteLine("UARTSendDONE function not found in AISExtra COFF file!!!");
                        return null;
                    }
                }
            }

            // Setup boolean indicating whether to include UARTSendDONE jump commands
            if ((devAISGen.bootMode == BootModes.UART) && (devAISGen.UARTSendDONEAddr != 0x0))
                devAISGen.SendUARTSendDONE = true;
            else
                devAISGen.SendUARTSendDONE = false;

            #endregion

            #region Write AIS MAGIC Number and initial data
            // Write the premilinary header and fields (everything before first AIS command)
            switch (devAISGen.bootMode)
            {
                case BootModes.EMIFA:
                    {
                        if (busWidth == 16)
                            tempAIS_bw.Write((UInt32)1);
                        else
                            tempAIS_bw.Write((UInt32)0);
                        tempAIS_bw.Write((UInt32)AIS.MagicNumber);
                        break;
                    }
                case BootModes.NAND:
                    {
                        tempAIS_bw.Write((UInt32)AIS.MagicNumber);
                        tempAIS_bw.Write((UInt32)0);
                        tempAIS_bw.Write((UInt32)0);
                        tempAIS_bw.Write((UInt32)0);
                        break;
                    }
                case BootModes.UART:
                    {
                        tempAIS_bw.Write((UInt32)AIS.MagicNumber);
                        break;
                    }
            };
            #endregion

            #region Send UARTSendDONE sections
            //Send UART code if it exists
            if (devAISGen.SendUARTSendDONE)
            {
                CRCCheckType tempCRCType = devAISGen.crcType;
                devAISGen.crcType = CRCCheckType.NO_CRC;
                devAISGen.SendUARTSendDONE = false;
                AISSectionLoad(AISExtrasCF, UARTSendDONE_TextSection, devAISGen);
                AISSectionLoad(AISExtrasCF, UARTSendDONE_DataSection, devAISGen);
                devAISGen.SendUARTSendDONE = true;
                devAISGen.crcType = tempCRCType;
            }
            #endregion

            #region ROM Function insertion

            // Insert words for ROM function execution
            for (UInt32 i = 0; i < devAISGen.ROMFunc.Length; i++)
            {
                for (UInt32 j = 0; j < iniSecs.Length; j++)
                {
                    if (iniSecs[j].iniSectionName.Equals(devAISGen.ROMFunc[i].iniSectionName))
                    {
                        UInt32 funcIndex = i;
                        tempAIS_bw.Write((UInt32)AIS.FunctionExec);
                        tempAIS_bw.Write((((UInt32)devAISGen.ROMFunc[i].numParams) << 16) + ((UInt32)funcIndex));
                        // Write Paramter values read from INI file
                        for (Int32 k = 0; k < devAISGen.ROMFunc[i].numParams; k++)
                        {
                            tempAIS_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToString()]);
                            Debug.DebugMSG(((UInt32)iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToString()]).ToString());
                        }
                        // Call UARTSendDONE from AIS Extras if this is for UART boot
                        if (devAISGen.SendUARTSendDONE)
                        {
                            tempAIS_bw.Write((UInt32)AIS.Jump);
                            tempAIS_bw.Write(devAISGen.UARTSendDONEAddr);
                        }
                    }
                }
            }

            #endregion

            #region AIS executable data download
            if (AISExtrasCF != null)
            {
                // Load the AISExtras COFF file
                AISCOFFLoad(AISExtrasCF, devAISGen);
            }
            #endregion

            #region AIS Extras init function execution
            //Insert calls for any AISExtra Init functions (like power domains)
            if (AISExtrasCF != null)
            {
                for (UInt32 i = 0; i < devAISGen.AISExtraFunc.Length; i++)
                {
                    if (devAISGen.AISExtraFunc[i].isInitFunc)
                    {
                        for (UInt32 j = 0; j < iniSecs.Length; j++)
                        {
                            if (iniSecs[j].iniSectionName.Equals(devAISGen.AISExtraFunc[i].iniSectionName))
                            {
                                for (UInt32 k = 0; k < devAISGen.AISExtraFunc[i].numParams; k++)
                                {
                                    // Write SET command
                                    tempAIS_bw.Write((UInt32)AIS.Set);
                                    //Write type field (32-bit only)
                                    tempAIS_bw.Write((UInt32)0x3);
                                    // Write appropriate parameter address
                                    tempAIS_bw.Write((UInt32) (devAISGen.AISExtraFunc[i].paramAddr + (k * 4)));
                                    //Write data to write
                                    tempAIS_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.AISExtraFunc[i].paramNames[k].ToString()]);
                                    //Write Sleep value (should always be zero)
                                    //tempAIS_bw.Write((UInt32)0x1000);
                                    tempAIS_bw.Write((UInt32)0x0);
                                }

                                // Now that params are set, Jump to function
                                tempAIS_bw.Write((UInt32)AIS.Jump);
                                tempAIS_bw.Write(devAISGen.AISExtraFunc[i].funcAddr);

                                // Call UARTSendDONE from AIS Extras if this is for UART boot
                                if (devAISGen.SendUARTSendDONE)
                                {
                                    tempAIS_bw.Write((UInt32)AIS.Jump);
                                    tempAIS_bw.Write(devAISGen.UARTSendDONEAddr);
                                }
                            }
                        }
                    }
                }
            }
            #endregion

            #region Application COFF file creation and loading
            // Create the COFF file object for the main application being loaded
            if (File.Exists(coffFileName))
            {
                // The file exists, so use it
                cf = new COFFFile(coffFileName);
                Debug.DebugMSG("FileName {0} found.", coffFileName);
            }
            else
            {
                Debug.DebugMSG("FileName {0} NOT found.", coffFileName);
                throw new FileNotFoundException("AISGen: COFF file, " + coffFileName + ", not found.");
            }

            if (cf != null)
            {
                // Load the AISExtras COFF file
                AISCOFFLoad(cf, devAISGen);
            }

            #endregion

            #region Insert Final JUMP_CLOSE command
            tempAIS_bw.Write((UInt32)AIS.Jump_Close);
            tempAIS_bw.Write((UInt32)cf.Header["optEntryPoint"]);
            numTargetSections = (UInt32)cf.Header["numTargetSections"];
            if (AISExtrasCF != null)
            {
                numTargetSections += (UInt32)AISExtrasCF.Header["numTargetSections"];
            }

            tempAIS_bw.Write((UInt32)numTargetSections);
            //tempAIS_bw.Write((UInt32)0x0);

            //tempAIS_bw.Write((UInt32)totalLoadableSize);
            tempAIS_bw.Write((UInt32)0x0);

            // Flush the data to the file and then return to start
            devAISGen.devAISFileStream.Close();
            #endregion

            #endregion

            #region Prepare the return byte array
            // Now create return Byte array based on tempAIS file and the bootmode
            EndianBinaryReader tempAIS_br;
            tempAIS_br = new EndianBinaryReader(
                    new FileStream(devAISGen.devAISFileName, FileMode.Open, FileAccess.Read),
                    Endian.LittleEndian);

            ASCIIEncoding enc = new ASCIIEncoding();

            // Setup the binary reader object
            if (devAISGen.bootMode == BootModes.UART)
            {
                numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
                devAISGen.AISData = new Byte[numWords << 3];   //Each word converts to 8 ASCII bytes
            }
            else
            {
                numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
                devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes
            }

            Debug.DebugMSG("Number of words in the stream is {0}", numWords);

            // Copy the data to the output Byte array
            for (UInt32 i = 0; i < numWords; i++)
            {
                if (devAISGen.bootMode == BootModes.UART)
                    enc.GetBytes(tempAIS_br.ReadUInt32().ToString("X8")).CopyTo(devAISGen.AISData, i * 8);
                else
                    BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
            }

            // Close the binary reader
            tempAIS_br.Close();

            // Delete the temp AIS data file
            File.Delete(devAISGen.devAISFileName);

            // Close the COFF files since we are done with them
            AISExtrasCF.Close();
            cf.Close();

            // Clean up any embedded file resources that may have been extracted
            EmbeddedFileIO.CleanUpEmbeddedFiles();

            #endregion

            // Console output
            Console.WriteLine("AIS file generation was successful.");
            // ---------------------------------------------------------
            // ******************* END AIS GENERATION ******************
            // ---------------------------------------------------------

            // Return Byte Array
            return devAISGen.AISData;
        }
Exemple #7
0
        /*
         * I've been studying the NSBCA format heavily over the last few days trying to figure it out.
         * I've determined that the first offset in a joint animation contains Pivoting data, and the second section contains Rotation data.
         * Rotation keyframes are called when the second byte equals 0 and Pivot keyframes are called when it equals 128, however the data itself is definitely stored a little differently to how it is stored in NSBMD files.
         * Scaling keyframes hold two scaling values for whatever reason, with Translation keyframes being just straight values that can be a signed word/dword.
         * Each animation has a frame length, however each object in an animation seems to have a start and end position that typically don't match up with the total number of frames.
         * Now I haven't had much experience with model animations, but I'm guessing this might have like a decay effect on the animation if anyone has ever played around with animations in Maya?
         * The trickiest part is calculating the right number of keyframes stored in each object as there isn't an actual value written down anywhere.
         * From what I can tell it's calculated based on a bunch of things including the difference in object frame length over animation frame length, the rate in which the object (and possibly the animation) plays back as well as rounding to the upper whole number.
         * This looks a bit funky and overcomplicated but so far all the animations I've been working with calculate the correct number of keyframes, so I'm assuming I'm on the right track.
         * Am yet to get to the point of loading animations into a model, but hopefully I won't get some spastic result :S

        Object Flag: --zyx-Sr-RZYX-T-
        > found in the header of  each object of an animation
        ===========================
        T - has Translation keyframes (0 Yes| 1 No)
        XYZ - flags for Translation attributes
        R - has Rotation/Pivot keyframes (0 Yes| 1 No)
        r - flag for Rotation/Pivot attribute
        S - has Scale keyframes (0 Yes| 1 No)
        xyz - flags for Scale attributes
        ===========================
        if T-XYZ = 1
        > Fixed Translation value (signed dword)
        if R-r = 1
        > Fixed Rotation/Pivot value (dword/2*word?)
        if S-xyz = 1
        > Fixed Scale value (2*dword)

        Note: The below is only done when the bit flag equals 0 for that attribute (TX, TY, TZ, R/P, SX, SY, SZ)

        a|b = datasize = playback speed
        > a & b are flags stored in the object header for each attribute

        Translate
        -----------------------------------------------------------
        2|0 = word = 1/1
        2|1 = word = 1/2
        2|2 = word = 1/3
        0|1 = dword = 1/2

        Rotate
        -----------------------------------------------------------
        0|0 = 2*byte = 1/1
        0|1 = 2*byte = 1/2
        0|2 = 2*byte = 1/3
        > byte0 = index
        > byte1 = 0 Rotation | 128 Pivot
        > not completely sure on rotation yet

        Scale
        -----------------------------------------------------------
        2|1 = 2*word = 1/1
        2|1 = 2*word = 1/2
        -----------------------------------------------------------

        Attribute    [animation flag|start|end|a|b] bytes/keyframes - animation length
        > bytes - the actual size of the data stored
        > keyframes - bytes/datasize(see above)

        Basabasa - 0 Pivot - 33 Rotation
        ===========================================================
        Translate	 [3|0|34|2|1] 38/19 - 36 Frames
        Rotate	 [3|0|34|0|1] 38/19 - 36 Frames
        Scale		 [3|0|34|2|1] 76/19 - 36 Frames
        ===========================================================

        Basabasa2 - 1 Pivot - 20 Rotation
        ===========================================================
        Rotate	 [3|0|78|0|1] 82/41 - 80 Frames
        ===========================================================

        Bilikyu - 31 Pivot
        ===========================================================
        Translate	 [3|0|58|2|1] 62/31 - 60 Frames
        Rotate	 [3|0|58|0|1] 62/31 - 60 Frames
        ===========================================================

        Donketu - 12 Pivot / 20 Rotation
        ===========================================================
        Translate	 [3|0|10|0|1] 24/06 - 11 Frames (dword)
        Translate	 [3|0|10|2|1] 12/06 - 11 Frames
        Translate	 [1|0|02|2|0] 04/02 - 02 Frames
        Rotate	 [3|0|10|0|1] 14/07 - 11 Frames
        ===========================================================

        Gesso - 39 Pivot
        ===========================================================
        Translate	 [0|0|16|2|2] 14/07 - 19 Frames
        Translate	 [0|0|16|2|2] 12/06 - 18 Frames
        Translate	 [0|0|12|2|2] 10/05 - 14 Frames
        Scale		 [0|0|16|2|2] 28/07 - 19 Frames
        Scale		 [0|0|16|2|2] 24/06 - 18 Frames
        Rotate	 [0|0|16|0|2] 16/08 - 19 Frames
        Rotate	 [0|0|16|0|2] 16/08 - 18 Frames
        Rotate	 [0|0|12|0|2] 14/07 - 14 Frames
        ===========================================================

        TTL Bird
        ===========================================================
        Translate	 [1|0|05|2|0] 10/05 - 05 Frames
        Rotate	 [1|0|05|0|0] 10/05 - 05 Frames
        ===========================================================

        Gamaguchi - 11 Pivot - 52 Rotation
        ===========================================================
        Translate	 [3|0|08|2|0] 16/08 - 08 Frames
        Translate	 [3|0|07|2|0] 14/07 - 07 Frames
        Translate	 [3|0|16|2|0] 32/16 - 16 Frames
        Rotate	 [3|0|08|0|0] 16/08 - 08 Frames
        Rotate	 [1|0|07|0|0] 14/07 - 07 Frames
        Rotate	 [3|0|16|0|0] 32/16 - 16 Frames
        Scale		 [3|0|08|2|0] 32/08 - 08 Frames
        Scale		 [1|0|07|2|0] 28/07 - 07 Frames
        ===========================================================
         */
        public static NSBCA_File Read(string Filename)
        {
            byte[] file_ = File.ReadAllBytes(Filename);
            if (file_[0] == 76 && file_[1] == 90 && file_[2] == 55 && file_[3] == 55)
            {
            }
            EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(file_), Endianness.LittleEndian);
            NSBCA_File ns = new NSBCA_File();
            ns.Header.ID = er.ReadString(Encoding.ASCII, 4);
            if (ns.Header.ID == "BCA0")
            {
                ns.Header.Magic = er.ReadBytes(4);
                ns.Header.file_size = er.ReadInt32();
                ns.Header.header_size = er.ReadInt16();
                ns.Header.nSection = er.ReadInt16();
                ns.Header.Section_Offset = new Int32[ns.Header.nSection];
                for (int i = 0; i < ns.Header.nSection; i++)
                {
                    ns.Header.Section_Offset[i] = er.ReadInt32();
                }

                ns.JNT0.ID = er.ReadString(Encoding.ASCII, 4);
                if (ns.JNT0.ID == "JNT0")
                {
                    ns.JNT0.Size = er.ReadInt32();
                    //3D Info Structure
                    ns.JNT0.dummy = er.ReadByte();
                    ns.JNT0.num_objs = er.ReadByte();
                    ns.JNT0.section_size = er.ReadInt16();
                    ns.JNT0.unknownBlock.header_size = er.ReadInt16();
                    ns.JNT0.unknownBlock.section_size = er.ReadInt16();
                    ns.JNT0.unknownBlock.constant = er.ReadInt32();
                    ns.JNT0.unknownBlock.unknown1 = new short[ns.JNT0.num_objs];
                    ns.JNT0.unknownBlock.unknown2 = new short[ns.JNT0.num_objs];
                    for (int i = 0; i < ns.JNT0.num_objs; i++)
                    {
                        ns.JNT0.unknownBlock.unknown1[i] = er.ReadInt16();
                        ns.JNT0.unknownBlock.unknown2[i] = er.ReadInt16();
                    }

                    ns.JNT0.infoBlock.header_size = er.ReadInt16();
                    ns.JNT0.infoBlock.data_size = er.ReadInt16();
                    ns.JNT0.infoBlock.Data = new NSBCA_File.jnt0.Info.info[ns.JNT0.num_objs];
                    for (int i = 0; i < ns.JNT0.num_objs; i++)
                    {
                        ns.JNT0.infoBlock.Data[i].Objectoffset = er.ReadInt32();
                    }
                    ns.JNT0.names = new string[ns.JNT0.num_objs];
                    for (int i = 0; i < ns.JNT0.num_objs; i++)
                    {
                        ns.JNT0.names[i] = er.ReadString(Encoding.ASCII, 16).Replace("\0", "");
                    }
                    ns.JAC = new NSBCA_File.J_AC[ns.JNT0.num_objs];
                    for (int i = 0; i < ns.JNT0.num_objs; i++)
                    {
                        er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.JNT0.infoBlock.Data[i].Objectoffset;
                        ns.JAC[i].ID = er.ReadString(Encoding.ASCII, 4);
                        if (ns.JAC[i].ID == "J" + (char)0x00 + "AC")
                        {
                            ns.JAC[i].NrFrames = er.ReadInt16();
                            ns.JAC[i].NrObjects = er.ReadInt16();
                            ns.JAC[i].Unknown1 = er.ReadInt32();
                            ns.JAC[i].Offset1 = er.ReadInt32();
                            ns.JAC[i].Offset2 = er.ReadInt32();
                            long curposs = er.BaseStream.Position;
                            if (ns.JAC[i].Offset2 != ns.JAC[i].Offset1)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.JNT0.infoBlock.Data[i].Objectoffset + ns.JAC[i].Offset1;
                                ns.JAC[i].JointData = er.ReadBytes(ns.JAC[i].Offset2 - ns.JAC[i].Offset1);
                                er.BaseStream.Position = curposs;
                            }

                            long dataoffset = 0;

                            ns.JAC[i].ObjInfoOffset = new Int32[ns.JAC[i].NrObjects];
                            for (int j = 0; j < ns.JAC[i].NrObjects; j++)
                            {
                                ns.JAC[i].ObjInfoOffset[j] = er.ReadInt16();
                            }

                            ns.JAC[i].ObjInfo = new NSBCA_File.J_AC.objInfo[ns.JAC[i].NrObjects];

                            for (int j = 0; j < ns.JAC[i].NrObjects; j++)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] +/* ns.JNT0.section_size*/ns.JNT0.infoBlock.Data[i].Objectoffset + ns.JAC[i].ObjInfoOffset[j];// + 8;
                                ns.JAC[i].ObjInfo[j].Flag = er.ReadInt16();
                                ns.JAC[i].ObjInfo[j].Unknown1 = er.ReadByte();
                                ns.JAC[i].ObjInfo[j].ID = er.ReadByte();
                                ns.JAC[i].ObjInfo[j].translate = new List<float>[3];
                                ns.JAC[i].ObjInfo[j].translate[0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].translate[1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].translate[2] = new List<float>();
                                ns.JAC[i].ObjInfo[j].translate_keyframes = new List<float>[3];
                                ns.JAC[i].ObjInfo[j].translate_keyframes[0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].translate_keyframes[1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].translate_keyframes[2] = new List<float>();
                                ns.JAC[i].ObjInfo[j].rotate = new List<float>();
                                ns.JAC[i].ObjInfo[j].rotate_keyframes = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].rotate_keyframes[0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].rotate_keyframes[1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale = new List<float>[3][];
                                ns.JAC[i].ObjInfo[j].scale[0] = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].scale[1] = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].scale[2] = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].scale[0][0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale[0][1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale[1][0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale[1][1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale[2][0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale[2][1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale_keyframes = new List<float>[3][];
                                ns.JAC[i].ObjInfo[j].scale_keyframes[0] = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].scale_keyframes[1] = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].scale_keyframes[2] = new List<float>[2];
                                ns.JAC[i].ObjInfo[j].scale_keyframes[0][0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale_keyframes[0][1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale_keyframes[1][0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale_keyframes[1][1] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale_keyframes[2][0] = new List<float>();
                                ns.JAC[i].ObjInfo[j].scale_keyframes[2][1] = new List<float>();
                                double[] speed = {
                1.0D, 0.5D, 0.33333333333333331D
            };
                                if (((ns.JAC[i].ObjInfo[j].Flag >> 1) & 1) == 0)
                                {
                                    //struct.DModelAnimation.MTransformAni trans[] = new struct.DModelAnimation.MTransformAni[3];
                                    //string msg = new StringBuilder().Append(msg).Append("\n   -> Translate: ").ToString();
                                    //string[] type = { "X", "Y", "Z" };
                                    for (int k = 0; k < 3; k++)
                                    {
                                        //trans[k] = new struct.DModelAnimation.MTransformAni(this);
                                        int tflag = ns.JAC[i].ObjInfo[j].Flag >> 3 + k & 1;
                                        //msg = new StringBuilder().Append(msg).Append("\n    -> T").Append(type[k]).Append(tflag).Append("[").ToString();
                                        if (tflag == 1)
                                        {
                                            int tvar = er.ReadInt32();
                                            //trans[k].setFrame((float)tvar / divide);
                                            ns.JAC[i].ObjInfo[j].translate[k].Add((float)tvar / 4096f);
                                            //msg = (new StringBuilder()).Append(msg).Append(tvar).ToString();
                                            continue;
                                        }
                                        else
                                        {
                                            int param2 = er.ReadInt32();
                                            int startFrame = param2 & 0xffff;
                                            ns.JAC[i].ObjInfo[j].tStart = startFrame;
                                            int endFrame = param2 >> 16 & 0xfff;
                                            ns.JAC[i].ObjInfo[j].tEnd = endFrame;
                                            int var2 = param2 >> 28 & 3;
                                            int speedId = param2 >> 30 & 3;
                                            int toffset = er.ReadInt32();
                                            int width = var2 != 0 ? 2 : 4;
                                            int extra = (ns.JAC[i].Unknown1 != 3 ? 0 : ns.JAC[i].NrFrames - endFrame);
                                            int length = (int)Math.Ceiling((double)(ns.JAC[i].NrFrames + extra) * speed[speedId]);
                                            long curpos = er.BaseStream.Position;
                                            for (int t = 0; t < length; t++)
                                            {
                                                er.BaseStream.Position = ns.Header.Section_Offset[0] +/* ns.JNT0.section_size*/ns.JNT0.infoBlock.Data[i].Objectoffset + toffset + (t * width);
                                                if (dataoffset == 0)
                                                {
                                                    dataoffset = toffset;
                                                }
                                                float keyFrame = (width != 2 ? (float)er.ReadInt32() : (float)er.ReadInt16());
                                                ns.JAC[i].ObjInfo[j].translate_keyframes[k].Add((float)LibNDSFormats.NSBMD.NsbmdGlRenderer.sign((int)keyFrame, (width != 2 ? 32 : 16)) / 4096f);
                                                //m = (new StringBuilder()).append(m).append("\n     -> #").append(t).append(": ").append(keyFrame).toString();
                                            }
                                            er.BaseStream.Position = curpos;
                                        }
                                    }
                                }
                                if (((ns.JAC[i].ObjInfo[j].Flag >> 6) & 1) == 0)
                                {
                                    int rflag = ns.JAC[i].ObjInfo[j].Flag >> 8 & 1;
                                    if (rflag == 1)
                                    {
                                        //dataParser _tmp14 = pa;
                                        int rvar = er.ReadInt32(); //dataParser.getInt(data, jump, 4);
                                        ns.JAC[i].ObjInfo[j].rotate.Add((float)rvar);
                                        //msg = (new StringBuilder()).append(msg).append(rvar).toString();
                                        //jump += 4;
                                    }
                                    else
                                    {
                                        int param2 = er.ReadInt32();
                                        int startFrame = param2 & 0xffff;
                                        ns.JAC[i].ObjInfo[j].rStart = startFrame;
                                        int endFrame = param2 >> 16 & 0xfff;
                                        ns.JAC[i].ObjInfo[j].rEnd = endFrame;
                                        int var2 = param2 >> 28 & 3;
                                        int speedId = param2 >> 30 & 3;
                                        int roffset = er.ReadInt32();
                                        int width = 2;//var2 != 0 ? 2 : 4;
                                        int length = (int)Math.Ceiling((double)(ns.JAC[i].NrFrames) * speed[speedId]);
                                        long curpos = er.BaseStream.Position;
                                        for (int r = 0; r < length; r++)
                                        {
                                            er.BaseStream.Position = ns.Header.Section_Offset[0] +/* ns.JNT0.section_size*/ns.JNT0.infoBlock.Data[i].Objectoffset + roffset + (r * width);
                                            if (dataoffset == 0)
                                            {
                                                dataoffset = roffset;
                                            }
                                            int rvar6 = er.ReadInt16();
                                            int rindex = rvar6 & 0x7fff;
                                            int mode = rvar6 >> 15 & 1;
                                            ns.JAC[i].ObjInfo[j].rotate_keyframes[0].Add(rindex);
                                            ns.JAC[i].ObjInfo[j].rotate_keyframes[1].Add(mode);
                                        }
                                        er.BaseStream.Position = curpos;

                                    }
                                }
                                if ((ns.JAC[i].ObjInfo[j].Flag >> 9 & 1) == 0)
                                {
                                    //struct.DModelAnimation.MScaleAni scale[] = new struct.DModelAnimation.MScaleAni[3];
                                    //msg = (new StringBuilder()).append(msg).append("\n   -> Scale: ").toString();
                                    for (int k = 0; k < 3; k++)
                                    {
                                        //scale[k] = new struct.DModelAnimation.MScaleAni(this);
                                        int sflag = ns.JAC[i].ObjInfo[j].Flag >> 11 + k & 1;
                                        //msg = (new StringBuilder()).append(msg).append("\n    -> S").append(type[k]).append(sflag).append("[").toString();
                                        if (sflag == 1)
                                        {
                                            //dataParser _tmp19 = pa;
                                            int svar1 = er.ReadInt32();//dataParser.getInt(data, jump, 4);
                                            ns.JAC[i].ObjInfo[j].scale[k][0].Add((float)svar1 / 4096f);
                                            //dataParser _tmp20 = pa;
                                            int svar2 = er.ReadInt32();//dataParser.getSign(data, jump + 4, 4);
                                            ns.JAC[i].ObjInfo[j].scale[k][1].Add((float)svar2 / 4096f);

                                            //int svar3 = er.ReadInt32();//dataParser.getSign(data, jump + 4, 4);
                                            //int svar4 = er.ReadInt32();//dataParser.getSign(data, jump + 4, 4);
                                            //ns.JAC[i].ObjInfo[j].scale[k][1].Add((float)svar2 / 4096f);
                                            //scale[k].setFrame(new float[] {
                                            //    (float)svar1 / divide, (float)svar2 / divide
                                            //});
                                            //msg = (new StringBuilder()).append(msg).append(svar1).append("|").append(svar2).toString();
                                            //jump += 8;
                                            continue;
                                        }
                                        else
                                        {
                                            int param2 = er.ReadInt32();
                                            int startFrame = param2 & 0xffff;
                                            ns.JAC[i].ObjInfo[j].sStart = startFrame;
                                            int endFrame = param2 >> 16 & 0xfff;
                                            ns.JAC[i].ObjInfo[j].sEnd = endFrame;
                                            int var2 = param2 >> 28 & 3;
                                            int speedId = param2 >> 30 & 3;
                                            int soffset = er.ReadInt32();
                                            int width = var2 != 0 ? 2 : 4;
                                            int length = (int)Math.Ceiling((double)(ns.JAC[i].NrFrames) * speed[speedId]);
                                            long curpos = er.BaseStream.Position;
                                            for (int s = 0; s < length; s++)
                                            {
                                                er.BaseStream.Position = ns.Header.Section_Offset[0] +/* ns.JNT0.section_size*/ns.JNT0.infoBlock.Data[i].Objectoffset + soffset + (s * width * 2);
                                                if (dataoffset == 0)
                                                {
                                                    dataoffset = soffset;
                                                }
                                                ns.JAC[i].ObjInfo[j].scale_keyframes[k][0].Add((float)(width != 2 ? (float)er.ReadInt32() : (float)er.ReadInt16()) / 4096f);
                                                ns.JAC[i].ObjInfo[j].scale_keyframes[k][1].Add((float)(width != 2 ? (float)er.ReadInt32() : (float)er.ReadInt16()) / 4096f);
                                            }
                                            er.BaseStream.Position = curpos;
                                        }
                                    }
                                }
                            }
                            if (dataoffset != 0)
                            {
                                curposs = er.BaseStream.Position;
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.JNT0.infoBlock.Data[i].Objectoffset + ns.JAC[i].Offset2;
                                ns.JAC[i].RotationData = er.ReadBytes((int)dataoffset - ns.JAC[i].Offset2);
                                er.BaseStream.Position = curposs;
                            }
                        }
                        else
                        {
                            //MessageBox.Show("Error");
                            er.Close();
                            return ns;
                        }
                    }
                }
                else
                {
                    //MessageBox.Show("Error");
                    er.Close();
                    return ns;
                }
            }
            else
            {
                //MessageBox.Show("Error");
                er.Close();
                return ns;
            }
            er.Close();
            return ns;
        }
        private void SaveFiles()
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string savePath = saveFileDialog1.FileName;

                FileStream originalArc = new FileStream(ArcFilePath, FileMode.Open);

                EndianBinaryReader reader = new EndianBinaryReader(originalArc, GameFormatReader.Common.Endian.Big);

                List<byte> testList = reader.ReadBytes((int)reader.BaseStream.Length).ToList();

                reader.Close();

                List<Message> exportList = new List<Message>();

                foreach (Message mes in MessageList)
                {
                    mes.ProofReadTagstoCodes();

                    Message temp = mes.Copy();

                    exportList.Add(temp);
                }

                byte[] newBMGFile = TextBankClass.ExportBMGFromPath(exportList);

                testList.RemoveRange(1344, testList.Count - 1344);

                testList.AddRange(newBMGFile);

                byte[] newBMCFile = ColorClass.BMCExporter(ColorList);

                testList.RemoveRange(256, newBMCFile.Length);

                testList.InsertRange(256, newBMCFile);

                FileStream testStream = new FileStream(savePath, FileMode.Create);

                EndianBinaryWriter writer = new EndianBinaryWriter(testStream, Endian.Big);

                writer.Write(testList.ToArray());

                writer.BaseStream.Position = 128;

                writer.Write((int)newBMGFile.Length);

                writer.BaseStream.Position = 4;

                writer.Write((int)testList.Count);

                writer.Flush();

                writer.Close();
            }
        }
Exemple #9
0
        /// <summary>
        /// SecureGenAIS command.
        /// </summary>
        /// <param name="coffFileName">File name of input .out file</param>
        /// <param name="bootMode">AISGen Object for the particular device</param>
        /// <returns>Bytes of the binary or AIS boot image</returns>
        public static Byte[] SecureGenAIS(String coffFileName,
            AISGen devAISGen,
            INISection[] iniSecs)
        {
            UInt32 busWidth = 8;
              UInt32 addrWidth = 16;
              UInt32 numTargetSections = 0;
              UInt32 numWords;
              UInt32 entryPoint = 0x00000000;
              Boolean seqReadEn = false;     // Not supported on all devices

              Byte[] secureKeyData = null;
              String currHashAlgorithmString = "SHA1";  // Default hash algorithm

              Hashtable UARTSendDONE_DataSection=null, UARTSendDONE_TextSection=null;

              // Hash tables to keep track of the input object and binary files
              List<SecureObjectFile> objectFiles = new List<SecureObjectFile>();
              List<SecureBinaryFile> binaryFiles = new List<SecureBinaryFile>();

              // COFF file objects for the main application and the AIS extras executable
              COFFFile AISExtrasCF=null;

              // Set defaults
              devAISGen.secureType              = SecureType.NONE;
              devAISGen.bootLoaderExitType      = BootLoaderExitType.NONE;
              devAISGen.currHashAlgorithmValue  = SHA_Algorithm.SHA1;
              devAISGen.finalFxnName            = null;
              devAISGen.sectionsToEncrypt       = null;
              devAISGen.rsaObject               = null;
              devAISGen.customerEncryptionKey   = null;
              devAISGen.keyEncryptionKey        = null;
              devAISGen.genericKeyHeaderData    = null;
              devAISGen.currHashAlgorithm       = null;
              devAISGen.signatureByteCnt        = 0;
              devAISGen.signatureCnt            = 0;
              // List to keep track of loadable sections and their occupied memory ranges
              devAISGen.sectionMemory = new List<MemoryRange>();

              // Setup the binary writer to generate the temp AIS file
              devAISGen.devAISStream              = new MemoryStream();
              EndianBinaryWriter tempAIS_bw       = new EndianBinaryWriter( devAISGen.devAISStream, devAISGen.devEndian);

              // Setup the binary writer to store data for signing
              devAISGen.signatureStream           = new MemoryStream();
              EndianBinaryWriter sig_bw           = new EndianBinaryWriter( devAISGen.signatureStream, devAISGen.devEndian);

              #region INI Data parsing
              // Get data from the GENERAL INI Section
              for (UInt32 i = 0; i < iniSecs.Length; i++)
              {
            INISection sec = iniSecs[i];
            if (sec.iniSectionName.Equals("GENERAL", StringComparison.OrdinalIgnoreCase))
            {
              foreach (DictionaryEntry de in sec.sectionValues)
              {
            // Read buswidth
            if (((String)de.Key).Equals("BUSWIDTH", StringComparison.OrdinalIgnoreCase))
              busWidth = (UInt32)sec.sectionValues["BUSWIDTH"];

            // Read BootMode (unless already set)
            if ((((String)de.Key).Equals("BOOTMODE", StringComparison.OrdinalIgnoreCase)) && (devAISGen.bootMode == BootModes.NONE))
              devAISGen.bootMode = (BootModes) Enum.Parse(typeof(BootModes), (String)sec.sectionValues["BOOTMODE"], true);

              // Read Addr width (for I2C/SPI)
            if (((String)de.Key).Equals("ADDRWIDTH", StringComparison.OrdinalIgnoreCase))
              addrWidth = (UInt32)sec.sectionValues["ADDRWIDTH"];

            // Sequential Read ENABLE
            if (((String)de.Key).Equals("SEQREADEN", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["SEQREADEN"]).Equals("ON", StringComparison.OrdinalIgnoreCase))
                seqReadEn = true;
              if (((String)sec.sectionValues["SEQREADEN"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                seqReadEn = true;
            }

            // Finalize fxn symbol name
            if (((String)de.Key).Equals("FINALFXNSYMBOLNAME", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.finalFxnName = (String)sec.sectionValues["FINALFXNSYMBOLNAME"];
            }

            // Read entrypoint value
            if (((String)de.Key).Equals("ENTRYPOINT", StringComparison.OrdinalIgnoreCase))
              entryPoint = (UInt32)sec.sectionValues["ENTRYPOINT"];
              }
            }

            if (sec.iniSectionName.Equals("SECURITY", StringComparison.OrdinalIgnoreCase))
            {
              foreach (DictionaryEntry de in sec.sectionValues)
              {
            // Security Type
            if (((String)de.Key).Equals("SECURITYTYPE", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.secureType = (SecureType) Enum.Parse(typeof(SecureType), (String)sec.sectionValues["SECURITYTYPE"], true);
            }

            // Boot exit type
            if (((String)de.Key).Equals("BOOTEXITTYPE", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.bootLoaderExitType = (BootLoaderExitType) Enum.Parse(typeof(BootLoaderExitType), (String)sec.sectionValues["BOOTEXITTYPE"], true);
            }

            // Encrypted section settings
            if (((String)de.Key).Equals("ENCRYPTSECTIONS", StringComparison.OrdinalIgnoreCase))
            {
              Char[] separators = new Char[]{','};
              String encryptSections = (String)sec.sectionValues["ENCRYPTSECTIONS"];
              devAISGen.sectionsToEncrypt = encryptSections.Split(separators,StringSplitOptions.RemoveEmptyEntries);
              for( int k = 0; k<devAISGen.sectionsToEncrypt.Length; k++)
              {
                devAISGen.sectionsToEncrypt[k] = devAISGen.sectionsToEncrypt[k].Trim();
              }
            }

            // AES Encryption Key (CEK)
            if (((String)de.Key).Equals("ENCRYPTIONKEY", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.customerEncryptionKey = new Byte[16];
              devAISGen.CEKInitialValue = new Byte[16];
              String keyString = (String)sec.sectionValues["ENCRYPTIONKEY"];
              if (keyString.Length != 32)
              {
                Console.WriteLine("AES Encryption Key is wrong length!");
                return null;
              }
              for (int j=0; j<keyString.Length; j+=2)
              {
                devAISGen.customerEncryptionKey[(j>>1)] = Convert.ToByte(keyString.Substring(j,2),16);
              }

              // Generate IV as encrypted version of AES Key
              using (MemoryStream ms = new MemoryStream(devAISGen.CEKInitialValue))
              {
                Aes myAES = new AesManaged();
                myAES.KeySize = 128;
                myAES.Mode = CipherMode.ECB;
                myAES.Padding = PaddingMode.None;
                ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.customerEncryptionKey, new Byte[16]);
                CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
                cs.Write(devAISGen.customerEncryptionKey,0,devAISGen.customerEncryptionKey.Length);
              }

              FileIO.SetFileData("cek.bin",devAISGen.customerEncryptionKey,true);
              FileIO.SetFileText("FROM_cek.init",KeyToBinaryString(devAISGen.customerEncryptionKey,0xA,true,true),true);
              FileIO.SetFileData("cek_cbc_iv.bin",devAISGen.CEKInitialValue,true);
            }

            // Key Encryption Key (not normally known, here for debug/testing purposes)
            if (((String)de.Key).Equals("KEYENCRYPTIONKEY", StringComparison.OrdinalIgnoreCase))
            {
              devAISGen.keyEncryptionKey = new Byte[16];
              String keyString = (String)sec.sectionValues["KEYENCRYPTIONKEY"];
              if (keyString.Length != 32)
              {
                Console.WriteLine("Key Encryption Key is wrong length!");
                return null;
              }
              for (int j=0; j<keyString.Length; j+=2)
              {
                devAISGen.keyEncryptionKey[(j>>1)] = Convert.ToByte(keyString.Substring(j,2),16);
              }

              FileIO.SetFileData("kek.bin",devAISGen.keyEncryptionKey,true);
              FileIO.SetFileText("FROM_kek.init",KeyToBinaryString(devAISGen.keyEncryptionKey,0xE,true,true),true);
            }

            // Generic Secure Option to force JTAG off as part of the key loading
            if (((String)de.Key).Equals("GENERICJTAGFORCEOFF", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["GENERICJTAGFORCEOFF"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                devAISGen.genericJTAGForceOff = true;
              else
                devAISGen.genericJTAGForceOff = false;
            }

            // Generic Secure Option to select the hash algorithm for signatures
            if (((String)de.Key).Equals("GENERICSHASELECTION", StringComparison.OrdinalIgnoreCase))
            {
              currHashAlgorithmString = (String)sec.sectionValues["GENERICSHASELECTION"];
              devAISGen.currHashAlgorithmValue = (SHA_Algorithm) Enum.Parse(typeof(SHA_Algorithm), (String)sec.sectionValues["GENERICSHASELECTION"], true);
            }

            // Generic Key Header file
            if (((String)de.Key).Equals("GENKEYHEADERFILENAME", StringComparison.OrdinalIgnoreCase))
            {
              String genKeyHeaderFileName = (String)sec.sectionValues["GENKEYHEADERFILENAME"];
              devAISGen.genericKeyHeaderData = new Byte[32];
              // Open file, read contents, copy to our AIS array
              using (FileStream tempFS = new FileStream(genKeyHeaderFileName, FileMode.Open, FileAccess.Read))
              {
                tempFS.Read(devAISGen.genericKeyHeaderData,0,32);
              }
            }

            // Custom Secure RSA Key File
            if (((String)de.Key).Equals("RSAKEYFILENAME", StringComparison.OrdinalIgnoreCase))
            {
              String rsaKeyFileName = (String)sec.sectionValues["RSAKEYFILENAME"];
              devAISGen.rsaObject = RSAKey.LoadFromFile(rsaKeyFileName);

              if (devAISGen.rsaObject == null)
              {
                Console.WriteLine("RSA key loading failed!");
                return null;
              }

              // Update the hash algo string if RSA key size is 2048 bits
              if (devAISGen.rsaObject.KeySize == 2048)
              {
                currHashAlgorithmString = "SHA256";
                devAISGen.currHashAlgorithmValue = SHA_Algorithm.SHA256;
              }
              Console.WriteLine("MapNameToOid({1}) = {0}",CryptoConfig.MapNameToOID(currHashAlgorithmString),currHashAlgorithmString);
            }
              }
            }

            if (sec.iniSectionName.Equals("SECURELEGACY", StringComparison.OrdinalIgnoreCase))
            {
              foreach (DictionaryEntry de in sec.sectionValues)
              {
            // Legacy secure option to encrypt the boot image
            if (((String)de.Key).Equals("ENCRYPTIMAGE", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["ENCRYPTIMAGE"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                devAISGen.secureLegacyEncryptImage = true;
              else
                devAISGen.secureLegacyEncryptImage = false;
            }
              }

              devAISGen.bootMode = BootModes.LEGACY;
            }

            if (sec.iniSectionName.Equals("BINARYINPUTFILE", StringComparison.OrdinalIgnoreCase))
            {
              SecureBinaryFile currFile = new SecureBinaryFile();
              currFile.fileName = null;
              currFile.useEntryPoint = false;
              currFile.loadAddr = 0x00000000;
              currFile.entryPointAddr = 0x00000000;
              currFile.encrypt = false;

              foreach (DictionaryEntry de in sec.sectionValues)
              {

            // File name for binary section data
            if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
            {
               currFile.fileName = (String) sec.sectionValues["FILENAME"];
            }

            // Binary section's load address in the memory map
            if (((String)de.Key).Equals("LOADADDRESS", StringComparison.OrdinalIgnoreCase))
            {
              currFile.loadAddr = (UInt32) sec.sectionValues["LOADADDRESS"];
            }

            // Binary section's entry point address in the memory map
            if (((String)de.Key).Equals("ENTRYPOINTADDRESS", StringComparison.OrdinalIgnoreCase))
            {
              currFile.entryPointAddr = (UInt32) sec.sectionValues["ENTRYPOINTADDRESS"];
            }

            // Option to specify that this entry point should be used for AIS
            if (((String)de.Key).Equals("USEENTRYPOINT", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
            }

            // Option to specify that this entry point should be used for AIS
            if (((String)de.Key).Equals("ENCRYPT", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["ENCRYPT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                currFile.encrypt = true;
              if (((String)sec.sectionValues["ENCRYPT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                currFile.encrypt = true;
            }
              }

              if (currFile.fileName == null)
              {
            Console.WriteLine("ERROR: File name must be provided for binary input file.");
            return null;
              }

              if (currFile.loadAddr == 0x00000000)
              {
            Console.WriteLine("ERROR: Valid load address must be provided for binary input file.");
            return null;
              }

              binaryFiles.Add(currFile);
            }

            if (sec.iniSectionName.Equals("OBJECTINPUTFILE", StringComparison.OrdinalIgnoreCase))
            {
              SecureObjectFile currFile = new SecureObjectFile();
              currFile.useEntryPoint = false;
              currFile.fileName = null;
              currFile.encrypt = false;

              foreach (DictionaryEntry de in sec.sectionValues)
              {
            // File name for binary section data
            if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
            {
               currFile.fileName = (String) sec.sectionValues["FILENAME"];
            }

            // Option to specify that this entry point should be used for AIS
            if (((String)de.Key).Equals("USEENTRYPOINT", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
              if (((String)sec.sectionValues["USEENTRYPOINT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                currFile.useEntryPoint = true;
            }

            // Option to specify that this entry point should be used for AIS
            if (((String)de.Key).Equals("ENCRYPT", StringComparison.OrdinalIgnoreCase))
            {
              if (((String)sec.sectionValues["ENCRYPT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                currFile.encrypt = true;
              if (((String)sec.sectionValues["ENCRYPT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                currFile.encrypt = true;
            }
              }

              if (currFile.fileName == null)
              {
            Console.WriteLine("ERROR: File name must be provided for input object file.");
            return null;
              }

              objectFiles.Add(currFile);
            }
              }

              #endregion

              #region INI data validation
              // INI Input Validation
              // 1) Make sure a secure type has been specified
              if (devAISGen.secureType == SecureType.NONE)
              {
            Console.WriteLine("ERROR: The device's security type was not specified!");
            return null;
              }
              else
              {
            Console.WriteLine("Creating boot image for a {0} secure device.",devAISGen.secureType.ToString().ToLower());
            // 2) Make sure we have a CEK and IV
            if (devAISGen.customerEncryptionKey == null)
            {
              Console.WriteLine("ERROR: No encryption key was specified!");
              return null;
            }

            // 3) If custom secure, make sure we have an rsaObject and CEK
            if ((devAISGen.secureType == SecureType.CUSTOM) && (devAISGen.rsaObject == null))
            {
              Console.WriteLine("ERROR: No RSA key file was specified!");
              return null;
            }

            // 3b) Make sure RSA key size is supported
            if ((devAISGen.secureType == SecureType.CUSTOM) && (devAISGen.rsaObject != null))
            {
              if ( (devAISGen.rsaObject.KeySize != 1024) && (devAISGen.rsaObject.KeySize != 2048) )
              {
            Console.WriteLine("ERROR: No RSA key size is invalid!");
            return null;
              }
              else
              {
            Console.WriteLine("INFO: RSA key is {0} bits.",devAISGen.rsaObject.KeySize);
              }
            }

            // 4) Specify Boot Exit type (if not legacy boot)
            if (devAISGen.bootMode != BootModes.LEGACY)
            {
              if (devAISGen.bootLoaderExitType == BootLoaderExitType.NONE)
              {
            Console.WriteLine("ERROR: No boot loader exit type was specified!");
            return null;
              }
              else
              {
            Console.WriteLine("INFO: Boot exit type has been selected as {0}.",devAISGen.bootLoaderExitType);
              }
            }
            // 5) If generic secure, make sure we have the CEK header info (either encrypted or unencrypted)
            if ((devAISGen.secureType == SecureType.GENERIC) && (devAISGen.genericKeyHeaderData == null))
            {
              Console.WriteLine("WARNING: Encrypted Key Header data is absent - generating plaintext version. ");
              Console.WriteLine("         The Customer Encryption Key will be transferred in plaintext!  ");
            }

            // 6) Give warning if generic device and no sections are specified for encryption
            if (devAISGen.bootMode != BootModes.LEGACY)
            {
              if ((devAISGen.secureType == SecureType.GENERIC) && (devAISGen.sectionsToEncrypt == null))
              {
            Console.WriteLine("WARNING: Generic Secure device was specified, but no input sections were indicated for encryption.");
            Console.WriteLine("         Only boot image signing will take place.");
              }
            }
              }

              // 2) Make sure valid hash algorithm was selected
              try
              {
            devAISGen.currHashAlgorithm = HashAlgorithm.Create(currHashAlgorithmString);
            Console.WriteLine("INFO: Current SHA algorithm is {0}.",devAISGen.currHashAlgorithmValue);
              }
              catch (Exception e)
              {
            Console.WriteLine("Invalid Hash Algorithm Selected. Exception message: {0}.",e.Message);
            return null;
              }

              #endregion

              #region Secure Key Structure and Data preparation

              if ( devAISGen.secureType == SecureType.GENERIC )
              {
            if ((devAISGen.genericKeyHeaderData != null) && (devAISGen.genericKeyHeaderData.Length >= 32))
            {
              // Create our own key header
              secureKeyData = new Byte[32];
              Array.Copy(devAISGen.genericKeyHeaderData,0,secureKeyData,0,32);
            }
            else
            {
              // Create our own key header
              secureKeyData = new Byte[32];

              // Init with Random Data
              (new Random()).NextBytes(secureKeyData);

              // Copy in the magic word for the generic key header structure
              BitConverter.GetBytes((UInt32)SecureLoadMagic.GENKEY_MAGIC).CopyTo(secureKeyData, 0);

              // Insert JTAGForceOff word
              BitConverter.GetBytes( (UInt32) (devAISGen.genericJTAGForceOff ? 0x00000001 : 0x00000000) ).CopyTo(secureKeyData, 4);

              // Inset Hash algorithm selection word (right now default to SHA-1
              BitConverter.GetBytes( (UInt32)devAISGen.currHashAlgorithmValue ).CopyTo(secureKeyData, 8);

              // Insert key Data (at offset 16)
              devAISGen.customerEncryptionKey.CopyTo(secureKeyData, 16);

              // FIXME: For debug write the data out to file
              FileIO.SetFileData("gen_keyhdr_unencrypted.bin",secureKeyData,true);

              // FIXME: Debug to write out the encrypted CEK structure (encrypted with KEK, using KEK encrypted KEK as IV)
              if (devAISGen.keyEncryptionKey != null)
              {
            Byte[] iv = new Byte[16];
            using (MemoryStream ms = new MemoryStream(iv))
            {
              Aes myAES = new AesManaged();
              myAES.KeySize = 128;
              myAES.Mode = CipherMode.ECB;
              myAES.Padding = PaddingMode.None;
              ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.keyEncryptionKey, new Byte[16]);
              CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
              cs.Write(devAISGen.keyEncryptionKey,0,devAISGen.keyEncryptionKey.Length);
            }

            Byte[] encSecureKeyData = new Byte[32];
            using (MemoryStream ms = new MemoryStream(encSecureKeyData))
            {
              Aes myAES = new AesManaged();
              myAES.KeySize = 128;
              myAES.Mode = CipherMode.CBC;
              myAES.Padding = PaddingMode.None;
              ICryptoTransform encryptor = myAES.CreateEncryptor(devAISGen.keyEncryptionKey, iv);
              CryptoStream cs = new CryptoStream(ms,encryptor,CryptoStreamMode.Write);
              cs.Write(secureKeyData,0,secureKeyData.Length);
            }

            // FIXME: For debug write the data out to file
            FileIO.SetFileData("gen_keyhdr_encrypted.bin",encSecureKeyData,true);
              }

            }
              }
              else if ( devAISGen.secureType == SecureType.CUSTOM )
              {
            // Create RPK Verify Struct
            secureKeyData = RSAKey.CreateCustomSecureKeyVerifyStruct(devAISGen.rsaObject);
            FileIO.SetFileData("rpk_struct.bin",secureKeyData,true);

            // Calculate the SHA hash of the Root Public Key
            Byte[] digest = devAISGen.currHashAlgorithm.ComputeHash(secureKeyData);

              #if (!OLD_MPK_METHOD)
            for (int i=16;i<digest.Length;i++)
            {
              digest[i-16] ^= digest[i];
            }
              #endif

            // Write the expected MPK (hash of RPK structure truncated to 128 bits) in binary format to file mpk.bin
            Byte[] mpk = new Byte[16];
            Array.Copy(digest,0,mpk,0,16);
            FileIO.SetFileData("mpk.bin",mpk,true);
            FileIO.SetFileText("FROM_mpk.init",KeyToBinaryString(mpk,0x12,false,true),true);
              }

              #endregion

              #region Handle the case of Legacy boot mode

              if (devAISGen.bootMode == BootModes.LEGACY)
              {
            UInt32 fileSize = 0, secureDataSize = 0, totalImgSize = 0, paddingSize = 0;
            UInt32 loadAddr = 0;
            Byte[] fileData;

            // Validate an input binary file was given in the INI file
            if (binaryFiles.Count == 0)
            {
              Console.WriteLine("ERROR: You did not supply a binary file section in the INI file!");
              return null;
            }
            if (binaryFiles.Count > 1)
            {
              Console.WriteLine("WARNING: You supplied too many biinary file sections in the INI file.");
              Console.WriteLine("         Only using the first one.");
            }

            // Set load addr to start of L2 for legacy boot mode
            loadAddr = devAISGen.Cache[0].startAddr + 0x10;

            // Figure out the size of the secure data region (signature + keystruct)
            if (devAISGen.secureType == SecureType.CUSTOM)
            {
              // On custom secure we have rsa keySize bits for signature and modulus of key struct,
              // plus eight additional bytes from key struct
              secureDataSize = (UInt32) (8 + (devAISGen.rsaObject.KeySize >> 3) + (devAISGen.rsaObject.KeySize >> 3));
            }
            else if (devAISGen.secureType == SecureType.GENERIC)
            {
              // On generic secure we have 32 for key and HashSize bits rounded up to nearst 16 bytes
              // for signature data.
              secureDataSize = (UInt32) (32 + ((((devAISGen.currHashAlgorithm.HashSize >> 3)+15)>>4)<<4));
            }

            // Verify legacy input binary file exists, and get data if it does
            if (File.Exists(binaryFiles[0].fileName))
            {
              Byte[] tempFileData = FileIO.GetFileData(binaryFiles[0].fileName);

              fileSize = (UInt32) tempFileData.Length;

              totalImgSize = 16 + fileSize + secureDataSize;

              if (totalImgSize > 16*1024)
              {
            Console.WriteLine("The input image is too large.  Reduce its size by {0} bytes.", (totalImgSize - (16*1024)));
            return null;
              }

              // Figure out how much to pad input file region to acheive complete image ending on 1K boundary
              paddingSize = (((totalImgSize+1023) >> 10) << 10) - totalImgSize;

              // Copy to final data array of fileSize
              fileSize = fileSize + paddingSize;
              fileData = new Byte[fileSize];
              tempFileData.CopyTo(fileData,0);

              // Adjust total image size to final amount
              totalImgSize = 16 + fileSize + secureDataSize;
            }
            else
            {
              Console.WriteLine("Error: Binary file was not found!");
              return null;
            }

            if ( ((binaryFiles[0].entryPointAddr & 0x00FFFFFF) < loadAddr) ||
             ((binaryFiles[0].entryPointAddr & 0x00FFFFFF) > (loadAddr+fileSize)) )
            {
              Console.WriteLine("ERROR: Entry point falls outside load image region.");
              return null;
            }

            // Place header
            // Config Word - indicates total image size, nor width (if applicable)
            if (busWidth == 16)
            {
              tempAIS_bw.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xF) << 8)|(0x1 << 0)|(0x0 << 4)));
              sig_bw.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xF) << 8)|(0x1 << 0)|(0x0 << 4)));
            }
            else
            {
              tempAIS_bw.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xF) << 8)|(0x0 << 0)|(0x0 << 4)));
              sig_bw.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xF) << 8)|(0x0 << 0)|(0x0 << 4)));
            }
            devAISGen.signatureByteCnt += 4;

            // Magic Number   - indicates signed or encrypted
            if (devAISGen.secureLegacyEncryptImage)
            {
              tempAIS_bw.Write((UInt32)SecureLegacyMagic.ENCMOD_MAGIC);
              sig_bw.Write((UInt32)SecureLegacyMagic.ENCMOD_MAGIC);
            }
            else
            {
              tempAIS_bw.Write((UInt32)SecureLegacyMagic.SIGNMOD_MAGIC);
              sig_bw.Write((UInt32)SecureLegacyMagic.SIGNMOD_MAGIC);
            }
            devAISGen.signatureByteCnt += 4;

            // Entry Point    - where to jump within the image upon load
            tempAIS_bw.Write( (UInt32)binaryFiles[0].entryPointAddr );
            sig_bw.Write( (UInt32)binaryFiles[0].entryPointAddr );
            devAISGen.signatureByteCnt += 4;

            // SecureDataSize - size of data following image for key struct & signature
            tempAIS_bw.Write( (UInt32)secureDataSize );
            sig_bw.Write( (UInt32)secureDataSize );

            // Now place padded binary contents
            if (!devAISGen.secureLegacyEncryptImage)
            {
              // Non-encrypted section
              tempAIS_bw.Write(fileData);
              sig_bw.Write(fileData);
            }
            else
            {
              // Encrypted section
              // Write unencrypted data to the signature buffer
              sig_bw.Write(fileData);

              // Encrypt data using CBC algorithm
              try
              {
            Byte[] encData = AesManagedUtil.AesCTSEncrypt(fileData,devAISGen.customerEncryptionKey,devAISGen.CEKInitialValue);

            // Write encrypted section data out to AIS data stream
            tempAIS_bw.Write(encData);
              }
              catch(Exception e)
              {
            Console.WriteLine("Exception during encryption operation: {0}",e.Message);
              }
            }
            devAISGen.signatureByteCnt += (Int32) fileSize;

            // Now place the key data
            tempAIS_bw.Write(secureKeyData);
            sig_bw.Write(secureKeyData);
            devAISGen.signatureByteCnt += secureKeyData.Length;

            // Finally place the signature which covers the entire image
            SecureAISInsertSignature(devAISGen.signatureStream, devAISGen);

            // Flush the data and then return to start
            devAISGen.devAISStream.Flush();
            devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

            devAISGen.signatureStream.Close();

              }
              #endregion

              #region AIS Generation
              else
              {
            // ---------------------------------------------------------
            // ****************** BEGIN AIS GENERATION *****************
            // ---------------------------------------------------------
            Console.WriteLine("Begining the AIS file generation.");

            // Diaplay currently selected boot mode
            Console.WriteLine("AIS file being generated for bootmode: {0}.",Enum.GetName(typeof(BootModes),devAISGen.bootMode));

            #region AIS Extras and UARTSendDONE Setup
            //Create the COFF file object for the AISExtras file (if it exists/is defined)
            if (devAISGen.AISExtraFileName != null)
            {
              EmbeddedFileIO.ExtractFile(Assembly.GetExecutingAssembly(), devAISGen.AISExtraFileName, false);

              if (File.Exists(devAISGen.AISExtraFileName))
              {
            // The file exists, so use it
            AISExtrasCF = new COFFFile(devAISGen.AISExtraFileName);
              }
              else
              {
            throw new FileNotFoundException("The AISExtra file, " + devAISGen.AISExtraFileName + ", was not found.");
              }
            }

            // If we have the AISExtras COFF file object, use it to setup the addresses
            // for the AISExtra functions.  These will utilize the L1P and L1D spaces that
            // are usually cache.
            if ( (AISExtrasCF != null) && (devAISGen.AISExtraFunc != null))
            {
              // Use symbols to get address for AISExtra functions and parameters
              for (Int32 i = 0; i < devAISGen.AISExtraFunc.Length; i++)
              {
            Hashtable sym = AISExtrasCF.symFind("_" + devAISGen.AISExtraFunc[i].funcName);
            devAISGen.AISExtraFunc[i].funcAddr = (UInt32)sym["value"];
            sym = AISExtrasCF.symFind(".params");
            devAISGen.AISExtraFunc[i].paramAddr = (UInt32)sym["value"];
              }

              // If the bootMode is UART we need the UARTSendDONE function
              if (devAISGen.bootMode == BootModes.UART)
              {
            // Set address for the UARTSendDone Function in the .text:uart section
            UARTSendDONE_TextSection = AISExtrasCF.secFind(".text:uart");
            UARTSendDONE_DataSection = AISExtrasCF.secFind(".data:uart");

            // Eliminate these as loadable since they will be loaded first, separate
            // from the main COFF file
            UARTSendDONE_TextSection["copyToTarget"] = false;
            UARTSendDONE_DataSection["copyToTarget"] = false;
            AISExtrasCF.Header["numTargetSections"] = ((UInt32)AISExtrasCF.Header["numTargetSections"] - (UInt32)2);

            // Set the actual run address for the UARTSendDONE function
            if ((UARTSendDONE_TextSection != null) && (UARTSendDONE_DataSection != null))
            {
              Debug.DebugMSG("UART section found");
              devAISGen.UARTSendDONEAddr = (UInt32)UARTSendDONE_TextSection["phyAddr"];
              Hashtable sym = AISExtrasCF.symFind("_UARTSendDONE");
              if (sym != null)
              {
                devAISGen.UARTSendDONEAddr = (UInt32)sym["value"];
                Debug.DebugMSG("UARTSendDONE at 0x{0:X8}",devAISGen.UARTSendDONEAddr);
              }
            }
            else
            {
              Console.WriteLine("UARTSendDONE function not found in AISExtra COFF file!!!");
              return null;
            }
              }
            }

            // Setup boolean indicating whether to include UARTSendDONE jump commands
            if ((devAISGen.bootMode == BootModes.UART) && (devAISGen.UARTSendDONEAddr != 0x0))
            devAISGen.SendUARTSendDONE = true;
            else
            devAISGen.SendUARTSendDONE = false;

            #endregion

            #region Write AIS MAGIC Number and initial data
            // Write the premilinary header and fields (everything before first AIS command)
            switch (devAISGen.bootMode)
            {
              case BootModes.EMIFA:
              {
            if (busWidth == 16)
              tempAIS_bw.Write((UInt32)(0x1 << 0)|(0x2 << 4));
            else
              tempAIS_bw.Write((UInt32)(0x0 << 0)|(0x2 << 4));
            tempAIS_bw.Write((UInt32)AIS.MagicNumber);
            break;
              }
              case BootModes.NAND:
              {
            tempAIS_bw.Write((UInt32)AIS.MagicNumber);
            tempAIS_bw.Write((UInt32)0);
            tempAIS_bw.Write((UInt32)0);
            tempAIS_bw.Write((UInt32)0);
            break;
              }
              case BootModes.UART:
              {
            tempAIS_bw.Write((UInt32)AIS.MagicNumber);
            break;
              }
              case BootModes.I2CMASTER:
              {
            if (addrWidth == 16)
              tempAIS_bw.Write((UInt32)2);
            else
              tempAIS_bw.Write((UInt32)1);
            tempAIS_bw.Write((UInt32)AIS.MagicNumber);
            break;
              }
              case BootModes.SPIMASTER:
              {
            if (addrWidth == 24)
              tempAIS_bw.Write((UInt32)3);
            else if (addrWidth == 16)
              tempAIS_bw.Write((UInt32)2);
            else
              tempAIS_bw.Write((UInt32)1);
            tempAIS_bw.Write((UInt32)AIS.MagicNumber);
            break;
              }
              default:
              {
            tempAIS_bw.Write((UInt32)AIS.MagicNumber);
            break;
              }
            };

            // Add the AIS magic number to signature buffer
            if ( devAISGen.secureType != SecureType.NONE )
            {
              sig_bw.Write((UInt32)AIS.MagicNumber);
              devAISGen.signatureByteCnt += 4;
            }
            #endregion

            #region Send Secure Key Load command and data
            tempAIS_bw.Write((UInt32)AIS.SecureKeyLoad);
            sig_bw.Write((UInt32)AIS.SecureKeyLoad);
            devAISGen.signatureByteCnt += 4;

            tempAIS_bw.Write(secureKeyData);
            sig_bw.Write(secureKeyData);
            devAISGen.signatureByteCnt += secureKeyData.Length;
            #endregion

            #region Send the exit mode type
            if ( devAISGen.secureType != SecureType.NONE )
            {
              // Write AIS opcode
              tempAIS_bw.Write((UInt32)AIS.SetSecExitMode);
              sig_bw.Write((UInt32)AIS.SetSecExitMode);

              // Write exit type
              tempAIS_bw.Write((UInt32)devAISGen.bootLoaderExitType);
              sig_bw.Write((UInt32)devAISGen.bootLoaderExitType);

              devAISGen.signatureByteCnt += 8;
            }
            #endregion

            #region Send UARTSendDONE sections
            // Send UART code if it exists
            if (devAISGen.SendUARTSendDONE)
            {
              CRCCheckType tempCRCType = devAISGen.crcType;
              devAISGen.crcType = CRCCheckType.NO_CRC;
              devAISGen.SendUARTSendDONE = false;
              SecureAISSectionLoad(AISExtrasCF, UARTSendDONE_TextSection, devAISGen, false);
              SecureAISSectionLoad(AISExtrasCF, UARTSendDONE_DataSection, devAISGen, false);
              devAISGen.SendUARTSendDONE = true;
              devAISGen.crcType = tempCRCType;
            }
            #endregion

            #region ROM Function insertion

            // Insert words for ROM function execution
            for (UInt32 i = 0; i < devAISGen.ROMFunc.Length; i++)
            {
              for (UInt32 j = 0; j < iniSecs.Length; j++)
              {
            if (iniSecs[j].iniSectionName.Equals(devAISGen.ROMFunc[i].iniSectionName))
            {
              UInt32 funcIndex = i;

              tempAIS_bw.Write((UInt32)AIS.FunctionExec);
              sig_bw.Write((UInt32)AIS.FunctionExec);
              devAISGen.signatureByteCnt += 4;

              tempAIS_bw.Write((((UInt32)devAISGen.ROMFunc[i].numParams) << 16) + ((UInt32)funcIndex));
              sig_bw.Write((((UInt32)devAISGen.ROMFunc[i].numParams) << 16) + ((UInt32)funcIndex));
              devAISGen.signatureByteCnt += 4;

              // Write Paramter values read from INI file
              for (Int32 k = 0; k < devAISGen.ROMFunc[i].numParams; k++)
              {
                //FIXME
                Debug.DebugMSG("\tParam name: {0}, Param num: {1}, Value: {2}\n",
                  devAISGen.ROMFunc[i].paramNames[k],
                  k,
                  iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToUpper()]);
                tempAIS_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToUpper()]);
                sig_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.ROMFunc[i].paramNames[k].ToUpper()]);
                devAISGen.signatureByteCnt += 4;
              }

              //Insert signature
              SecureAISInsertSignature(devAISGen.signatureStream,devAISGen);

              // Call UARTSendDONE from AIS Extras if this is for UART boot
              if (devAISGen.SendUARTSendDONE)
              {
                tempAIS_bw.Write((UInt32)AIS.Jump);
                tempAIS_bw.Write(devAISGen.UARTSendDONEAddr);

                sig_bw.Write((UInt32)AIS.Jump);
                sig_bw.Write(devAISGen.UARTSendDONEAddr);
                devAISGen.signatureByteCnt += 8;

                // Insert signature
                SecureAISInsertSignature(devAISGen.signatureStream,devAISGen);
              }
            }
              }
            }

            #endregion

            #region Insert seqread command
            if (seqReadEn == true)
            {
              tempAIS_bw.Write((UInt32)AIS.SeqReadEnable);
              sig_bw.Write((UInt32)AIS.SeqReadEnable);
              devAISGen.signatureByteCnt += 4;
            }

            #endregion

            #region AIS executable data download
            if (AISExtrasCF != null)
            {
              // Load the AISExtras COFF file
              SecureAISCOFFLoad(AISExtrasCF, devAISGen);

              // Increment section count
              numTargetSections += (UInt32)AISExtrasCF.Header["numTargetSections"];
            }
            #endregion

            #region AIS Extras init function execution
            //Insert calls for any AISExtra Init functions (like power domains)
            if (AISExtrasCF != null)
            {
              for (UInt32 i = 0; i < devAISGen.AISExtraFunc.Length; i++)
              {
            if (devAISGen.AISExtraFunc[i].isInitFunc)
            {
              for (UInt32 j = 0; j < iniSecs.Length; j++)
              {
                if (iniSecs[j].iniSectionName.Equals(devAISGen.AISExtraFunc[i].iniSectionName))
                {
                  for (UInt32 k = 0; k < devAISGen.AISExtraFunc[i].numParams; k++)
                  {
                    // Write SET command
                    tempAIS_bw.Write((UInt32)AIS.Set);
                    sig_bw.Write((UInt32)AIS.Set);

                    //Write type field (32-bit only)
                    tempAIS_bw.Write((UInt32)0x3);
                    sig_bw.Write((UInt32)0x3);

                    // Write appropriate parameter address
                    tempAIS_bw.Write((UInt32) (devAISGen.AISExtraFunc[i].paramAddr + (k * 4)));
                    sig_bw.Write((UInt32) (devAISGen.AISExtraFunc[i].paramAddr + (k * 4)));

                    //Write data to write
                    tempAIS_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.AISExtraFunc[i].paramNames[k].ToString()]);
                    sig_bw.Write((UInt32)iniSecs[j].sectionValues[devAISGen.AISExtraFunc[i].paramNames[k].ToString()]);

                    //Write Sleep value (should always be zero)
                    tempAIS_bw.Write((UInt32)0x0);
                    sig_bw.Write((UInt32)0x0);
                    devAISGen.signatureByteCnt += 20;

                    // Insert signature
                    SecureAISInsertSignature(devAISGen.signatureStream, devAISGen);
                  }

                  // Now that params are set, Jump to function
                  tempAIS_bw.Write((UInt32)AIS.Jump);
                  tempAIS_bw.Write(devAISGen.AISExtraFunc[i].funcAddr);
                  sig_bw.Write((UInt32)AIS.Jump);
                  sig_bw.Write(devAISGen.AISExtraFunc[i].funcAddr);
                  devAISGen.signatureByteCnt += 8;

                  // Insert signature
                  SecureAISInsertSignature(devAISGen.signatureStream, devAISGen);

                  // Call UARTSendDONE from AIS Extras if this is for UART boot
                  if (devAISGen.SendUARTSendDONE)
                  {
                    tempAIS_bw.Write((UInt32)AIS.Jump);
                    tempAIS_bw.Write(devAISGen.UARTSendDONEAddr);

                    sig_bw.Write((UInt32)AIS.Jump);
                    sig_bw.Write(devAISGen.UARTSendDONEAddr);
                    devAISGen.signatureByteCnt += 8;

                    // Insert signature
                    SecureAISInsertSignature(devAISGen.signatureStream, devAISGen);
                  }
                }
              }
            }
              }
            }
            #endregion

            Debug.DebugMSG("Starting binary file section loads.");

            #region Insert binary data files as SECTION_LOAD commands
            // Insert binary files
            for (Int32 i=0; i<binaryFiles.Count; i++)
            {
              if (File.Exists(binaryFiles[i].fileName))
              {
            SecureAISBinarySectionLoad(binaryFiles[i].fileName, devAISGen, binaryFiles[i].loadAddr, binaryFiles[i].encrypt);
            Debug.DebugMSG("Binary file {0} found.", binaryFiles[i].fileName);

            numTargetSections++;

            if (binaryFiles[i].useEntryPoint)
            {
              entryPoint = binaryFiles[i].entryPointAddr;
            }
              }
              else
              {
            Console.WriteLine("WARNING: Binary input file {0} was not found. Skipping.",binaryFiles[i].fileName);
              }
            }
            #endregion

            Debug.DebugMSG("Starting object file section loads.");

            #region COFF file parsing and loading
            // Create the COFF file object for the main application being loaded
            if (File.Exists(coffFileName))
            {
              SecureObjectFile currFile = new SecureObjectFile();
              currFile.useEntryPoint = true;
              currFile.fileName = coffFileName;
              currFile.encrypt = false;

              // Cycle throught all other object files loaded via INI file and unset their
              // useEntryPoint boolean, warning us as we do
              Boolean showWarning = false;
              for (Int32 i=0; i<objectFiles.Count; i++)
              {
            // Insert binary file
            if (objectFiles[i].useEntryPoint)
            {
              objectFiles[i].useEntryPoint = false;
              showWarning = true;
            }
              }

              if (showWarning)
            Console.WriteLine("WARNING: Ignoring useEntryPoint flag from all object file sections of INI file");

              objectFiles.Add(currFile);
            }

            // Insert object files
            for (Int32 i=0; i<objectFiles.Count; i++)
            {
              if (File.Exists(objectFiles[i].fileName))
              {
            // FIXME: Add support to detect ELF or COFF and support ELF parsing

            // Parse the object file
            COFFFile cf = new COFFFile(objectFiles[i].fileName);

            if (cf != null)
            {
              String[] tempEncryptString = null;
              if (objectFiles[i].encrypt)
              {
                // If this Object file is specified for encryption, temporarily set
                // global sectionsToEncrypt string to "ALL"
                tempEncryptString = devAISGen.sectionsToEncrypt;
                devAISGen.sectionsToEncrypt = new String[1]{"ALL"};

                // Load the object file contents
                SecureAISCOFFLoad(cf, devAISGen);

                // Increment section count
                numTargetSections += (UInt32)cf.Header["numTargetSections"];

                // If this Object file is specified for encryption, reset the
                // global sectionsToEncrypt string to its original value
                devAISGen.sectionsToEncrypt = tempEncryptString;
              }
              else
              {
                // Load the object file contents
                SecureAISCOFFLoad(cf, devAISGen);
              }
            }
            else
            {
              Console.WriteLine("ERROR: Parsing the input object file {0} failed!",objectFiles[i].fileName);
            }

            if (entryPoint == 0x00000000)
            {
              if (objectFiles[i].useEntryPoint)
              {
                entryPoint = (UInt32)cf.Header["optEntryPoint"];
              }
            }

            // Insert final function register function
            if (devAISGen.finalFxnName != null)
            {
              Hashtable symbol;
              // Look for the symbol in the Coff file symbols table
              symbol = cf.symFind(devAISGen.finalFxnName);

              // If found, insert the command
              if (symbol != null)
              {
                tempAIS_bw.Write((UInt32)AIS.FinalFxnReg);
                tempAIS_bw.Write((UInt32)symbol["value"]);
                sig_bw.Write((UInt32)AIS.FinalFxnReg);
                sig_bw.Write((UInt32)symbol["value"]);
                devAISGen.signatureByteCnt += 8;

                Console.WriteLine("Finalize function symbol, '{0}', found as address 0x{1:X8}.",devAISGen.finalFxnName,(UInt32)symbol["value"]);
              }
              else
              {
                Console.WriteLine("Finalize function symbol, '{0}', not found.",devAISGen.finalFxnName);
              }
            }

            // Close object file
            if (cf != null)
              cf.Close();
              }
              else
              {
            Console.WriteLine("WARNING: Input object file {0} was not found. Skipping.",objectFiles[i].fileName);
              }
            }

            #endregion

            #region Insert Final JUMP_CLOSE command
            tempAIS_bw.Write((UInt32)AIS.Jump_Close);
            tempAIS_bw.Write(entryPoint);
            sig_bw.Write((UInt32)AIS.Jump_Close);
            sig_bw.Write(entryPoint);
            devAISGen.signatureByteCnt += 8;

            if (entryPoint == 0x00000000)
              Console.WriteLine("WARNING: Entry point never set or set to invalid value");

            // Insert signature
            SecureAISInsertSignature(devAISGen.signatureStream, devAISGen);

            // Flush the data and then return to start
            devAISGen.devAISStream.Flush();
            devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

            devAISGen.signatureStream.Close();
            #endregion

            // Console output
            Console.WriteLine("AIS file generation was successful.");

            // ---------------------------------------------------------
            // ******************* END AIS GENERATION ******************
            // ---------------------------------------------------------
              }
              #endregion

              #region Prepare the return byte array
              // Now create return byte array based on AIS Stream data
              EndianBinaryReader tempAIS_br;
              tempAIS_br = new EndianBinaryReader(
              devAISGen.devAISStream,
              Endian.LittleEndian);

              numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
              devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes

              Debug.DebugMSG("Number of words in the stream is {0}", numWords);

              // Copy the data to the output Byte array
              for (UInt32 i = 0; i < numWords; i++)
              {
            BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
              }

              // Close the binary reader
              tempAIS_br.Close();

              // Close the COFF files since we are done with them
              if (AISExtrasCF != null)
            AISExtrasCF.Close();

              // Clean up any embedded file resources that may have been extracted
              EmbeddedFileIO.CleanUpEmbeddedFiles();

              #endregion

              // Return Byte Array
              return devAISGen.AISData;
        }
        public void LoadFromArc(string fileName)
        {
            string tempFileName = "";

            using (FileStream yaz0TestStream = new FileStream(fileName, FileMode.Open))
            {

                EndianBinaryReader yaz0TestReader = new EndianBinaryReader(yaz0TestStream, Endian.Big);

                string yaz0Test = yaz0TestReader.ReadString(4);

                if (yaz0Test == "Yaz0")
                {
                    byte[] uncompressedArc = DecodeYaz0(yaz0TestReader);

                    yaz0TestReader.Close();

                    fileName = Path.GetTempFileName();

                    tempFileName = fileName;

                    FileInfo info = new FileInfo(fileName);

                    info.Attributes = FileAttributes.Temporary;

                    using (FileStream tempStream = new FileStream(fileName, FileMode.Open))
                    {
                        EndianBinaryWriter tempWriter = new EndianBinaryWriter(tempStream, Endian.Big);

                        tempWriter.Write(uncompressedArc);

                        tempWriter.Flush();

                        tempWriter.Close();
                    }
                }
            }

            RARC loadedArc = new RARC(fileName);

            if (File.Exists(tempFileName))
            {
                File.Delete(tempFileName);
            }

            FilesFromArc = new List<FileData>();

            for (int i = 0; i < loadedArc.Nodes.Count(); i++)
            {
                for (int j = 0; j < loadedArc.Nodes[i].Entries.Count(); j++)
                {
                    if (loadedArc.Nodes[i].Entries[j].Data != null)
                    {
                        FileData file = new FileData();

                        file.Name = loadedArc.Nodes[i].Entries[j].Name;

                        file.Data = loadedArc.Nodes[i].Entries[j].Data;

                        FilesFromArc.Add(file);
                    }
                }
            }

            foreach (FileData file in FilesFromArc)
            {
                if (file.Name.Contains(".dzb"))
                {
                    using (EndianBinaryReader reader = new EndianBinaryReader(file.Data, Endian.Big))
                    {

                        Collision = new CollisionMesh();

                        Collision.Load(reader);
                    }
                }

                if (file.Name.Contains(".dzs") || file.Name.Contains(".dzr"))
                {
                    using (EndianBinaryReader reader = new EndianBinaryReader(file.Data, Endian.Big))
                    {
                        Read(reader);
                    }
                }

                if (file.Name.Contains(".bdl") || file.Name.Contains(".bmd"))
                {
                    //Not implemented
                }
            }
        }
Exemple #11
0
        public static NSBTP_File Read(string Filename)
        {
            EndianBinaryReader er = new EndianBinaryReader(File.OpenRead(Filename), Endianness.LittleEndian);
            NSBTP_File ns = new NSBTP_File();
            ns.Header.ID = er.ReadString(Encoding.ASCII, 4);
            if (ns.Header.ID == "BTP0")
            {
                ns.Header.Magic = er.ReadBytes(4);
                ns.Header.file_size = er.ReadInt32();
                ns.Header.header_size = er.ReadInt16();
                ns.Header.nSection = er.ReadInt16();
                ns.Header.Section_Offset = new Int32[ns.Header.nSection];
                for (int i = 0; i < ns.Header.nSection; i++)
                {
                    ns.Header.Section_Offset[i] = er.ReadInt32();
                }
                ns.PAT0.ID = er.ReadString(Encoding.ASCII, 4);
                if (ns.PAT0.ID == "PAT0")
                {
                    ns.PAT0.Size = er.ReadInt32();
                    //3D Info Structure
                    ns.PAT0.dummy = er.ReadByte();
                    ns.PAT0.num_objs = er.ReadByte();
                    ns.PAT0.section_size = er.ReadInt16();
                    ns.PAT0.unknownBlock.header_size = er.ReadInt16();
                    ns.PAT0.unknownBlock.section_size = er.ReadInt16();
                    ns.PAT0.unknownBlock.constant = er.ReadInt32();
                    ns.PAT0.unknownBlock.unknown1 = new short[ns.PAT0.num_objs];
                    ns.PAT0.unknownBlock.unknown2 = new short[ns.PAT0.num_objs];
                    for (int i = 0; i < ns.PAT0.num_objs; i++)
                    {
                        ns.PAT0.unknownBlock.unknown1[i] = er.ReadInt16();
                        ns.PAT0.unknownBlock.unknown2[i] = er.ReadInt16();
                    }

                    ns.PAT0.infoBlock.header_size = er.ReadInt16();
                    ns.PAT0.infoBlock.data_size = er.ReadInt16();
                    ns.PAT0.infoBlock.Data = new NSBTP_File.pat0.Info.info[ns.PAT0.num_objs];
                    for (int i = 0; i < ns.PAT0.num_objs; i++)
                    {
                        ns.PAT0.infoBlock.Data[i].MPToffset = er.ReadInt32();
                    }
                    ns.PAT0.names = new string[ns.PAT0.num_objs];
                    for (int i = 0; i < ns.PAT0.num_objs; i++)
                    {
                        ns.PAT0.names[i] = er.ReadString(Encoding.ASCII, 16).Replace("\0", "");
                    }

                    ns.MPT.ID = er.ReadString(Encoding.ASCII, 4);
                    if (ns.MPT.ID == "M" + (char)0x00 + "PT")
                    {
                        ns.MPT.NoFrames = er.ReadInt16();
                        ns.MPT.NoTex = er.ReadByte();
                        ns.MPT.NoPal = er.ReadByte();
                        ns.MPT.Texoffset = er.ReadInt16();
                        ns.MPT.Paloffset = er.ReadInt16();
                        //3D Info Structure
                        ns.MPT.dummy = er.ReadByte();
                        ns.MPT.num_objs = er.ReadByte();
                        ns.MPT.section_size = er.ReadInt16();
                        ns.MPT.unknownBlock.header_size = er.ReadInt16();
                        ns.MPT.unknownBlock.section_size = er.ReadInt16();
                        ns.MPT.unknownBlock.constant = er.ReadInt32();
                        ns.MPT.unknownBlock.unknown1 = new short[ns.MPT.num_objs];
                        ns.MPT.unknownBlock.unknown2 = new short[ns.MPT.num_objs];
                        for (int i = 0; i < ns.MPT.num_objs; i++)
                        {
                            ns.MPT.unknownBlock.unknown1[i] = er.ReadInt16();
                            ns.MPT.unknownBlock.unknown2[i] = er.ReadInt16();
                        }

                        ns.MPT.infoBlock.header_size = er.ReadInt16();
                        ns.MPT.infoBlock.data_size = er.ReadInt16();
                        ns.MPT.infoBlock.Data = new NSBTP_File.M_PT.Info.info[ns.MPT.num_objs];
                        ns.AnimData = new NSBTP_File.animData[ns.MPT.num_objs];
                        for (int i = 0; i < ns.MPT.num_objs; i++)
                        {
                            ns.MPT.infoBlock.Data[i].KeyFrames = er.ReadInt32();
                            ns.MPT.infoBlock.Data[i].Unknown1 = er.ReadInt16();
                            ns.MPT.infoBlock.Data[i].Offset = er.ReadInt16();
                            ns.AnimData[i].KeyFrames = new NSBTP_File.animData.keyFrame[ns.MPT.infoBlock.Data[i].KeyFrames];
                            for (int j = 0; j < ns.MPT.infoBlock.Data[i].KeyFrames; j++)
                            {
                                long curpos = er.BaseStream.Position;
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.PAT0.section_size + ns.MPT.infoBlock.Data[i].Offset + j*4 + 8;
                                ns.AnimData[i].KeyFrames[j].Start = er.ReadInt16();
                                ns.AnimData[i].KeyFrames[j].texId = er.ReadByte();
                                ns.AnimData[i].KeyFrames[j].palId = er.ReadByte();
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.PAT0.section_size + ns.MPT.Texoffset + ns.AnimData[i].KeyFrames[j].texId * 16 + 8;
                                ns.AnimData[i].KeyFrames[j].texName = LibNDSFormats.Utils.ReadNSBMDString(er);
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.PAT0.section_size + ns.MPT.Paloffset + ns.AnimData[i].KeyFrames[j].palId * 16 + 8;
                                ns.AnimData[i].KeyFrames[j].palName = LibNDSFormats.Utils.ReadNSBMDString(er);
                                er.BaseStream.Position = curpos;
                            }
                        }
                        ns.MPT.names = new string[ns.MPT.num_objs];
                        for (int i = 0; i < ns.MPT.num_objs; i++)
                        {
                            ns.MPT.names[i] = LibNDSFormats.Utils.ReadNSBMDString(er);
                        }
                    }
                    else
                    {
                        MessageBox.Show("NSBTP Error");
                        er.Close();
                        return ns;
                    }
                }
                else
                {
                    MessageBox.Show("NSBTP Error");
                    er.Close();
                    return ns;
                }
            }
            else
            {
                MessageBox.Show("NSBTP Error");
                er.Close();
                return ns;
            }
            er.Close();
            return ns;
        }
Exemple #12
0
        /// <summary>
        /// Load materials in stream.
        /// </summary>
        /// <param name="stream">Stream to use.</param>
        /// <returns>Material definitions.</returns>
        public static IEnumerable<NsbmdAnimation> ReadJnt0(Stream stream, int blockoffset)
        {
            EndianBinaryReader reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
            int blocksize, blockptr, blocklimit;
            int num, objnum, i, j, r;
            List<int> dataoffset = new List<int>();
            int sec1offset, sec2offset;
            NsbmdAnimation[] animation = new NsbmdAnimation[1];
            List<int> animlen = new List<int>();

            ////////////////////////////////////////////////
            // joint
            blockptr = blockoffset + 4;			// already read the ID, skip 4 bytes
            blocksize = reader.ReadInt32();		// block size
            blocklimit = blocksize + blockoffset;

            reader.ReadByte();					// skip dummy 0
            num = reader.ReadByte(); //assert(num > 0);	// no of joint must == 1
            Console.WriteLine("No. of Joint = %02x\n", num);

            //dataoffset = (int*)malloc(sizeof(int));
            //if (!dataoffset) return NULL;

            reader.BaseStream.Seek(10 + (num << 2), SeekOrigin.Current);		// skip [char xyz], useless
            blockptr += 10;

            reader.BaseStream.Seek(4, SeekOrigin.Current);				// go straight to joint data offset
            blockptr += 4;
            for (i = 0; i < num; i++)
                dataoffset.Add(getdword(reader.ReadBytes(4)) + blockoffset);

            //fseek( fnsbca, 16 * num, SEEK_CUR );		// skip names
            blockptr += 16 * num;

            for (i = 0; i < num; i++)
            {
                reader.BaseStream.Seek(dataoffset[i], SeekOrigin.Begin);
                //j = getdword();
                if (reader.ReadBytes(4) == new byte[] {0x4A,0x00,0x41,0x43 }) return null;
                blockptr += 4;

                animlen.Add(getword(reader.ReadBytes(2)));
                objnum = getword(reader.ReadBytes(2));
                //if (objnum != g_model[0].objnum) return NULL;
                blockptr += 4;

                //animation = (ANIMATION*)calloc(sizeof(ANIMATION), objnum);
                //if (!animation) return NULL;
                animation = new NsbmdAnimation[objnum];

                reader.BaseStream.Seek(4, SeekOrigin.Current);	// skip 4 zeros
                blockptr += 4;

                sec1offset = getdword(reader.ReadBytes(4)) + dataoffset[i];
                sec2offset = getdword(reader.ReadBytes(4)) + dataoffset[i];
                blockptr += 8;

                for (j = 0; j < objnum; j++)
                {
                    animation[j] = new NsbmdAnimation();
                    animation[j].dataoffset = getword(reader.ReadBytes(2)) + dataoffset[i];
                }

                for (j = 0; j < objnum; j++)
                {
                    NSBMD.NsbmdAnimation anim = animation[j];
                    r = getdword(reader.ReadBytes(4));
                    anim.flag = r;
                   // if ((r >> 1 & 1) == 0)
                    //{		// any transformation?
                    if ((r >> 1 & 1) == 0)
                        {	// translation
                            if ((r & 4) == 1)
                            {	// use Base T
                            }
                            else
                            {
                                if ((r & 8) == 1)
                                {	// consTX
                                    anim.m_trans[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
                                }
                                else
                                {
                                }
                                if ((r & 0x10) == 1)
                                {	// consTY
                                    anim.m_trans[1] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
                                }
                                else
                                {
                                }
                                if ((r & 0x20) == 1)
                                {	// consTZ
                                    anim.m_trans[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
                                }
                                else
                                {
                                }
                            }
                        }
                    if ((r >> 6 & 1) == 0)
                        {	// rotation
                            if ((r & 0x100) == 1)
                            {	// constR
                                anim.a = ((float)getword(reader.ReadBytes(2))) / 4096.0f;
                                anim.b = ((float)getword(reader.ReadBytes(2))) / 4096.0f;
                            }
                            else
                            {
                            }
                        }
                    if ((r >> 9 & 1) == 0)
                        {	// scale
                            if ((r & 0x400) == 1)
                            {	// use Base S
                            }
                            else
                            {
                                if ((r & 0x800) == 1)
                                {	// consSX
                                    anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
                                }
                                else
                                {
                                }
                                if ((r & 0x1000) == 1)
                                {// consSY
                                    anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
                                }
                                else
                                {
                                }
                                if ((r & 0x2000) == 1)
                                {// consSZ
                                    anim.m_scale[0] = ((float)getdword(reader.ReadBytes(4))) / 4096.0f;
                                }
                                else
                                {
                                }
                            }
                       // }
                    }
                    animation[j] = anim;
                }

            }
            reader.Close();
            //free(dataoffset);
            return animation;
        }
Exemple #13
0
        public static NSBTA_File Read(string Filename)
        {
            EndianBinaryReader er = new EndianBinaryReader(File.OpenRead(Filename), Endianness.LittleEndian);
            NSBTA_File ns = new NSBTA_File();
            ns.Header.ID = er.ReadString(Encoding.ASCII, 4);
            if (ns.Header.ID == "BTA0")
            {
                ns.Header.Magic = er.ReadBytes(4);
                ns.Header.file_size = er.ReadInt32();
                ns.Header.header_size = er.ReadInt16();
                ns.Header.nSection = er.ReadInt16();
                ns.Header.Section_Offset = new Int32[ns.Header.nSection];
                for (int i = 0; i < ns.Header.nSection; i++)
                {
                    ns.Header.Section_Offset[i] = er.ReadInt32();
                }
                ns.SRT0.ID = er.ReadString(Encoding.ASCII, 4);
                if (ns.SRT0.ID == "SRT0")
                {
                    ns.SRT0.Size = er.ReadInt32();
                    //3D Info Structure
                    ns.SRT0.dummy = er.ReadByte();
                    ns.SRT0.num_objs = er.ReadByte();
                    ns.SRT0.section_size = er.ReadInt16();
                    ns.SRT0.unknownBlock.header_size = er.ReadInt16();
                    ns.SRT0.unknownBlock.section_size = er.ReadInt16();
                    ns.SRT0.unknownBlock.constant = er.ReadInt32();
                    ns.SRT0.unknownBlock.unknown1 = new short[ns.SRT0.num_objs];
                    ns.SRT0.unknownBlock.unknown2 = new short[ns.SRT0.num_objs];
                    for (int i = 0; i < ns.SRT0.num_objs; i++)
                    {
                        ns.SRT0.unknownBlock.unknown1[i] = er.ReadInt16();
                        ns.SRT0.unknownBlock.unknown2[i] = er.ReadInt16();
                    }

                    ns.SRT0.infoBlock.header_size = er.ReadInt16();
                    ns.SRT0.infoBlock.data_size = er.ReadInt16();
                    ns.SRT0.infoBlock.Data = new NSBTA_File.srt0.Info.info[ns.SRT0.num_objs];
                    for (int i = 0; i < ns.SRT0.num_objs; i++)
                    {
                        ns.SRT0.infoBlock.Data[i].MAToffset = er.ReadInt32();
                    }
                    ns.SRT0.names = new string[ns.SRT0.num_objs];
                    for (int i = 0; i < ns.SRT0.num_objs; i++)
                    {
                        ns.SRT0.names[i] = er.ReadString(Encoding.ASCII, 16).Replace("\0", "");
                    }

                    ns.MAT.ID = er.ReadString(Encoding.ASCII, 4);
                    if (ns.MAT.ID == "M"+(char)0x00+"AT")
                    {
                        ns.MAT.Unknown1 = er.ReadInt16();
                        ns.MAT.Unknown2 = er.ReadByte();
                        ns.MAT.Unknown3 = er.ReadByte();
                        //3D Info Structure
                        ns.MAT.dummy = er.ReadByte();
                        ns.MAT.num_objs = er.ReadByte();
                        ns.MAT.section_size = er.ReadInt16();
                        ns.MAT.unknownBlock.header_size = er.ReadInt16();
                        ns.MAT.unknownBlock.section_size = er.ReadInt16();
                        ns.MAT.unknownBlock.constant = er.ReadInt32();
                        ns.MAT.unknownBlock.unknown1 = new short[ns.MAT.num_objs];
                        ns.MAT.unknownBlock.unknown2 = new short[ns.MAT.num_objs];
                        for (int i = 0; i < ns.MAT.num_objs; i++)
                        {
                            ns.MAT.unknownBlock.unknown1[i] = er.ReadInt16();
                            ns.MAT.unknownBlock.unknown2[i] = er.ReadInt16();
                        }

                        ns.MAT.infoBlock.header_size = er.ReadInt16();
                        ns.MAT.infoBlock.data_size = er.ReadInt16();
                        ns.MAT.infoBlock.Data = new NSBTA_File.M_AT.Info.info[ns.MAT.num_objs];
                        ns.SRTData = new NSBTA_File.srtData[ns.MAT.num_objs];
                        for (int i = 0; i < ns.MAT.num_objs; i++)
                        {
                            ns.MAT.infoBlock.Data[i].frame = new short[5];
                            ns.MAT.infoBlock.Data[i].var1 = new short[5];
                            ns.MAT.infoBlock.Data[i].var2 = new short[5];
                            ns.MAT.infoBlock.Data[i].var3 = new short[5];
                            ns.MAT.infoBlock.Data[i].frameStep = new int[5];
                            for (int j = 0; j < 5; j++)
                            {
                                ns.MAT.infoBlock.Data[i].frame[j] = er.ReadInt16();
                                ns.MAT.infoBlock.Data[i].var1[j] = (short)(er.ReadInt16() / 4096);
                                ns.MAT.infoBlock.Data[i].var2[j] = er.ReadInt16();
                                ns.MAT.infoBlock.Data[i].var3[j] = (short)(er.ReadInt16() / 4096);
                            }
                            if (ns.MAT.infoBlock.Data[i].var1[0] > 1)
                            {
                                ns.SRTData[i].scaleS = new decimal[1];
                                ns.SRTData[i].scaleS[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[0] / 4096);
                            }
                            else
                            {
                                ns.SRTData[i].scaleS = new decimal[ns.MAT.infoBlock.Data[i].frame[0]];
                            }
                            if (ns.MAT.infoBlock.Data[i].var1[1] > 1)
                            {
                                ns.SRTData[i].scaleT = new decimal[1];
                                ns.SRTData[i].scaleT[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[1] / 4096);
                            }
                            else
                            {
                                ns.SRTData[i].scaleT = new decimal[ns.MAT.infoBlock.Data[i].frame[1]];
                            }
                            if (ns.MAT.infoBlock.Data[i].var1[2] > 1)
                            {
                                ns.SRTData[i].rotate = new decimal[2];
                                ns.SRTData[i].rotate[0] = ns.MAT.infoBlock.Data[i].var2[2];
                                ns.SRTData[i].rotate[1] = ns.MAT.infoBlock.Data[i].var3[2];
                            }
                            else
                            {
                                ns.SRTData[i].rotate = new decimal[ns.MAT.infoBlock.Data[i].frame[2] * 2];
                            }
                            if (ns.MAT.infoBlock.Data[i].var1[3] > 1)
                            {
                                ns.SRTData[i].translateS = new decimal[1];
                                ns.SRTData[i].translateS[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[3] / 4096);
                            }
                            else
                            {
                                ns.SRTData[i].translateS = new decimal[ns.MAT.infoBlock.Data[i].frame[3]];
                                ns.MAT.infoBlock.Data[i].frameStep[3] = Math.Abs(ns.MAT.infoBlock.Data[i].var1[3] >> 1);

                            }
                            if (ns.MAT.infoBlock.Data[i].var1[4] > 1)
                            {
                                ns.SRTData[i].translateT = new decimal[1];
                                ns.SRTData[i].translateT[0] = Math.Abs(ns.MAT.infoBlock.Data[i].var2[4] / 4096);
                            }
                            else
                            {
                                ns.SRTData[i].translateT = new decimal[ns.MAT.infoBlock.Data[i].frame[4]];
                                ns.MAT.infoBlock.Data[i].frameStep[4] = Math.Abs(ns.MAT.infoBlock.Data[i].var1[4] >> 1);
                            }
                            //ns.SRTData[i].scaleS = new decimal[ns.MAT.infoBlock.Data[i].var1[0] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[0]];
                            //ns.SRTData[i].scaleT = new decimal[ns.MAT.infoBlock.Data[i].var1[1] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[1]];
                            //ns.SRTData[i].rotate = new decimal[ns.MAT.infoBlock.Data[i].var1[2] == 2 ? ns.MAT.infoBlock.Data[i].var1[2] == 3 ? 2 : 1 : ns.MAT.infoBlock.Data[i].frame[2]];
                            //ns.SRTData[i].translateS = new decimal[ns.MAT.infoBlock.Data[i].var1[3] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[3]];
                            //ns.SRTData[i].translateT = new decimal[ns.MAT.infoBlock.Data[i].var1[4] == 3 ? 1 : ns.MAT.infoBlock.Data[i].frame[4]];
                        }
                        ns.MAT.names = new string[ns.MAT.num_objs];
                        for (int i = 0; i < ns.MAT.num_objs; i++)
                        {
                            ns.MAT.names[i] = er.ReadString(Encoding.ASCII, 16).Replace("\0", "");
                        }
                        for (int i = 0; i < ns.MAT.num_objs; i++)
                        {
                            if (ns.SRTData[i].scaleS.Length != 1)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[0] + 8;
                                for (int j = 0; j < ns.SRTData[i].scaleS.Length; j++)
                                {
                                    ns.SRTData[i].scaleS[j] = (decimal)(er.ReadInt16() / 4096d);
                                }
                            }
                            if (ns.SRTData[i].scaleT.Length != 1)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[1] + 8;
                                for (int j = 0; j < ns.SRTData[i].scaleT.Length; j++)
                                {
                                    ns.SRTData[i].scaleT[j] = (decimal)(er.ReadInt16() / 4096d);
                                }
                            }
                            if (ns.SRTData[i].rotate.Length != 2)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[2] + 8;
                                for (int j = 0; j < ns.SRTData[i].rotate.Length; j++)
                                {
                                    ns.SRTData[i].rotate[j] = (decimal)(er.ReadInt16() / 4096d);
                                }
                            }
                            if (ns.SRTData[i].translateS.Length != 1)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[3] + 8;

                                for (int j = 0; j < ns.SRTData[i].translateS.Length; j += (ns.MAT.infoBlock.Data[i].frameStep[3] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[3]))
                                {
                                    decimal value = (decimal)(er.ReadInt16() / 4096d);
                                    for (int k = 0; k < (ns.MAT.infoBlock.Data[i].frameStep[3] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[3]); k++)
                                    {
                                        ns.SRTData[i].translateS[j + k] = value;
                                    }
                                }
                            }
                            if (ns.SRTData[i].translateT.Length != 1)
                            {
                                er.BaseStream.Position = ns.Header.Section_Offset[0] + ns.SRT0.section_size + ns.MAT.infoBlock.Data[i].var2[4] + 8;
                                for (int j = 0; j < ns.SRTData[i].translateT.Length; j +=( ns.MAT.infoBlock.Data[i].frameStep[4] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[4]))
                                {
                                    decimal value = (decimal)(er.ReadInt16() / 4096d);
                                    for (int k = 0; k < (ns.MAT.infoBlock.Data[i].frameStep[4] == 0 ? 1 : ns.MAT.infoBlock.Data[i].frameStep[4]); k++)
                                    {
                                        ns.SRTData[i].translateT[j + k] = value;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        MessageBox.Show("Error");
                        er.Close();
                        return ns;
                    }
                }
                else
                {
                    MessageBox.Show("Error");
                    er.Close();
                    return ns;
                }
            }
            else
            {
                MessageBox.Show("Error");
                er.Close();
                return ns;
            }
            er.Close();
            return ns;
        }
        // Gen V
        private void listBox6_SelectedIndexChanged(object sender, EventArgs e)
        {
            listBox5.Items.Clear();
            listBox4.Items.Clear();
            if (radioButton18.Checked == true)
            {
                editorTileset = workingFolder + @"data\a\0\1\tilesets";
            }
            else if (radioButton17.Checked == true)
            {
                editorTileset = workingFolder + @"data\a\1\7\bldtilesets";
            }
            else
            {
                editorTileset = workingFolder + @"data\a\1\7\bld2tilesets";
            }
            EndianBinaryReader er = new EndianBinaryReader(File.OpenRead(editorTileset + "\\" + listBox6.SelectedIndex.ToString("D4")), Endianness.LittleEndian);
            nsbtx = new NSBTX_File();
            if (er.ReadString(Encoding.ASCII, 4) != "BTX0")
            {
                MessageBox.Show(rm.GetString("tilesetError"), null, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                er.Close();
                return;
            }
            else
            {
                nsbtx.Header.ID = "BTX0";
                nsbtx.Header.Magic = er.ReadBytes(4);
                nsbtx.Header.file_size = er.ReadInt32();
                nsbtx.Header.header_size = er.ReadInt16();
                nsbtx.Header.nSection = er.ReadInt16();
                nsbtx.Header.Section_Offset = new Int32[nsbtx.Header.nSection];
                for (int i = 0; i < nsbtx.Header.nSection; i++)
                {
                    nsbtx.Header.Section_Offset[i] = er.ReadInt32();
                }
                nsbtx.TEX0.ID = er.ReadString(Encoding.ASCII, 4);
                if (nsbtx.TEX0.ID != "TEX0")
                {
                    MessageBox.Show(rm.GetString("tilesetError"));
                    er.Close();
                    return;
                }
            }
            nsbtx.TEX0.Section_size = er.ReadInt32();
            nsbtx.TEX0.Padding1 = er.ReadInt32();
            nsbtx.TEX0.Texture_Data_Size = (er.ReadInt16() << 3);
            nsbtx.TEX0.Texture_Info_Offset = er.ReadInt16();
            nsbtx.TEX0.Padding2 = er.ReadInt32();
            nsbtx.TEX0.Texture_Data_Offset = er.ReadInt32();
            nsbtx.TEX0.Padding3 = er.ReadInt32();
            nsbtx.TEX0.Compressed_Texture_Data_Size = (er.ReadInt16() << 3);
            nsbtx.TEX0.Compressed_Texture_Info_Offset = er.ReadInt16();
            nsbtx.TEX0.Padding4 = er.ReadInt32();
            nsbtx.TEX0.Compressed_Texture_Data_Offset = er.ReadInt32();
            nsbtx.TEX0.Compressed_Texture_Info_Data_Offset = er.ReadInt32();
            nsbtx.TEX0.Padding5 = er.ReadInt32();
            nsbtx.TEX0.Palette_Data_Size = (er.ReadInt32() << 3);
            nsbtx.TEX0.Palette_Info_Offset = er.ReadInt32();
            nsbtx.TEX0.Palette_Data_Offset = er.ReadInt32();

            nsbtx.TexInfo.dummy = er.ReadByte();
            nsbtx.TexInfo.num_objs = er.ReadByte();
            nsbtx.TexInfo.section_size = er.ReadInt16();

            nsbtx.TexInfo.unknownBlock.header_size = er.ReadInt16();
            nsbtx.TexInfo.unknownBlock.section_size = er.ReadInt16();
            nsbtx.TexInfo.unknownBlock.constant = er.ReadInt32();
            nsbtx.TexInfo.unknownBlock.unknown1 = new List<short>();
            nsbtx.TexInfo.unknownBlock.unknown2 = new List<short>();
            for (int i = 0; i < nsbtx.TexInfo.num_objs; i++)
            {
                nsbtx.TexInfo.unknownBlock.unknown1.Add(er.ReadInt16());
                nsbtx.TexInfo.unknownBlock.unknown2.Add(er.ReadInt16());
            }

            nsbtx.TexInfo.infoBlock.header_size = er.ReadInt16();
            nsbtx.TexInfo.infoBlock.data_size = er.ReadInt16();
            nsbtx.TexInfo.infoBlock.TexInfo = new NSBTX_File.texInfo.Info.texInfo[nsbtx.TexInfo.num_objs];
            //long compressedStartOffset = 0x00;
            for (int i = 0; i < nsbtx.TexInfo.num_objs; i++)
            {
                nsbtx.TexInfo.infoBlock.TexInfo[i].Texture_Offset = (er.ReadInt16() << 3);
                nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters = er.ReadInt16();
                nsbtx.TexInfo.infoBlock.TexInfo[i].Width = er.ReadByte();
                nsbtx.TexInfo.infoBlock.TexInfo[i].Unknown1 = er.ReadByte();
                nsbtx.TexInfo.infoBlock.TexInfo[i].Height = er.ReadByte();
                nsbtx.TexInfo.infoBlock.TexInfo[i].Unknown2 = er.ReadByte();
                nsbtx.TexInfo.infoBlock.TexInfo[i].coord_transf = (byte)(nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters & 14);
                nsbtx.TexInfo.infoBlock.TexInfo[i].color0 = (byte)((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 13) & 1);
                nsbtx.TexInfo.infoBlock.TexInfo[i].format = (byte)((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 10) & 7);
                nsbtx.TexInfo.infoBlock.TexInfo[i].height = (byte)(8 << ((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 7) & 7));
                nsbtx.TexInfo.infoBlock.TexInfo[i].width = (byte)(8 << ((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 4) & 7));
                nsbtx.TexInfo.infoBlock.TexInfo[i].flip_Y = (byte)((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 3) & 1);
                nsbtx.TexInfo.infoBlock.TexInfo[i].flip_X = (byte)((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 2) & 1);
                nsbtx.TexInfo.infoBlock.TexInfo[i].repeat_Y = (byte)((nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters >> 1) & 1);
                nsbtx.TexInfo.infoBlock.TexInfo[i].repeat_X = (byte)(nsbtx.TexInfo.infoBlock.TexInfo[i].Parameters & 1);
                nsbtx.TexInfo.infoBlock.TexInfo[i].depth = (byte)bpp[nsbtx.TexInfo.infoBlock.TexInfo[i].format];
                if (nsbtx.TexInfo.infoBlock.TexInfo[i].width == 0x00)
                    switch (nsbtx.TexInfo.infoBlock.TexInfo[i].Unknown1 & 0x3)
                    {
                        case 2:
                            nsbtx.TexInfo.infoBlock.TexInfo[i].width = 0x200;
                            break;
                        default:
                            nsbtx.TexInfo.infoBlock.TexInfo[i].width = 0x100;
                            break;
                    }
                if (nsbtx.TexInfo.infoBlock.TexInfo[i].height == 0x00)
                    switch ((nsbtx.TexInfo.infoBlock.TexInfo[i].Height >> 3) & 0x3)
                    {
                        case 2:
                            nsbtx.TexInfo.infoBlock.TexInfo[i].height = 0x200;
                            break;
                        default:
                            nsbtx.TexInfo.infoBlock.TexInfo[i].height = 0x100;
                            break;
                    }
                int imgsize = (nsbtx.TexInfo.infoBlock.TexInfo[i].width * nsbtx.TexInfo.infoBlock.TexInfo[i].height * nsbtx.TexInfo.infoBlock.TexInfo[i].depth) / 8;
                long curpos = er.BaseStream.Position;
                if (nsbtx.TexInfo.infoBlock.TexInfo[i].format != 5)
                {
                    er.BaseStream.Seek(nsbtx.TexInfo.infoBlock.TexInfo[i].Texture_Offset + nsbtx.Header.Section_Offset[0] + nsbtx.TEX0.Texture_Data_Offset, SeekOrigin.Begin);
                }
                else
                {
                    er.BaseStream.Seek(nsbtx.Header.Section_Offset[0] + nsbtx.TEX0.Compressed_Texture_Data_Offset + nsbtx.TexInfo.infoBlock.TexInfo[i].Texture_Offset, SeekOrigin.Begin);
                }
                nsbtx.TexInfo.infoBlock.TexInfo[i].Image = er.ReadBytes(imgsize);
                er.BaseStream.Seek(curpos, SeekOrigin.Begin);

                if (nsbtx.TexInfo.infoBlock.TexInfo[i].format == 5)
                {
                    //nsbtx.TexInfo.infoBlock.TexInfo[i].compressedDataStart = (uint)compressedStartOffset;
                    //compressedStartOffset += imgsize / 2;
                    curpos = er.BaseStream.Position;
                    er.BaseStream.Seek(nsbtx.Header.Section_Offset[0] + nsbtx.TEX0.Compressed_Texture_Info_Data_Offset + nsbtx.TexInfo.infoBlock.TexInfo[i].Texture_Offset / 2, SeekOrigin.Begin);
                    nsbtx.TexInfo.infoBlock.TexInfo[i].spData = er.ReadBytes(imgsize / 2);
                    er.BaseStream.Seek(curpos, SeekOrigin.Begin);
                }
            }
            nsbtx.TexInfo.names = new List<string>();
            for (int i = 0; i < nsbtx.TexInfo.num_objs; i++)
            {
                nsbtx.TexInfo.names.Add(er.ReadString(Encoding.ASCII, 16).Replace("\0", ""));
                listBox5.Items.Add(nsbtx.TexInfo.names[i]);
            }

            nsbtx.PalInfo.dummy = er.ReadByte();
            nsbtx.PalInfo.num_objs = er.ReadByte();
            nsbtx.PalInfo.section_size = er.ReadInt16();

            nsbtx.PalInfo.unknownBlock.header_size = er.ReadInt16();
            nsbtx.PalInfo.unknownBlock.section_size = er.ReadInt16();
            nsbtx.PalInfo.unknownBlock.constant = er.ReadInt32();
            nsbtx.PalInfo.unknownBlock.unknown1 = new List<short>();
            nsbtx.PalInfo.unknownBlock.unknown2 = new List<short>();
            for (int i = 0; i < nsbtx.PalInfo.num_objs; i++)
            {
                nsbtx.PalInfo.unknownBlock.unknown1.Add(er.ReadInt16());
                nsbtx.PalInfo.unknownBlock.unknown2.Add(er.ReadInt16());
            }

            nsbtx.PalInfo.infoBlock.header_size = er.ReadInt16();
            nsbtx.PalInfo.infoBlock.data_size = er.ReadInt16();
            nsbtx.PalInfo.infoBlock.PalInfo = new NSBTX_File.palInfo.Info.palInfo[nsbtx.PalInfo.num_objs];
            for (int i = 0; i < nsbtx.PalInfo.num_objs; i++)
            {
                nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset = (er.ReadInt16() << 3);
                nsbtx.PalInfo.infoBlock.PalInfo[i].Color0 = er.ReadInt16();
                er.BaseStream.Position -= 4;
                int palBase = er.ReadInt32();
                int palAddr = palBase & 0xfff;
                long curpos = er.BaseStream.Position;
                er.BaseStream.Seek(nsbtx.Header.Section_Offset[0] + nsbtx.TEX0.Palette_Data_Offset, SeekOrigin.Begin);
                er.BaseStream.Seek(nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset, SeekOrigin.Current);
                nsbtx.PalInfo.infoBlock.PalInfo[i].pal = Tinke.Convertir.BGR555(er.ReadBytes(nsbtx.TEX0.Palette_Data_Size - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset));
                er.BaseStream.Seek(curpos, SeekOrigin.Begin);
            }
            nsbtx.PalInfo.names = new List<string>();
            for (int i = 0; i < nsbtx.PalInfo.num_objs; i++)
            {
                nsbtx.PalInfo.names.Add(er.ReadString(Encoding.ASCII, 16).Replace("\0", ""));
                listBox4.Items.Add(nsbtx.PalInfo.names[i]);
            }
            List<int> offsets = new List<int>();
            for (int i = 0; i < nsbtx.PalInfo.num_objs; i++)
            {
                //if(!offsets.Contains(nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset))
                //{
                offsets.Add(nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset);
                //}
            }
            offsets.Add((int)er.BaseStream.Length);
            offsets.Sort();
            for (int i = 0; i < nsbtx.PalInfo.num_objs; i++)
            {
                int pallength;
                int j = -1;
                do
                {
                    j++;
                }
                while (offsets[j] - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset <= 0);//nsbtx.PalInfo.infoBlock.PalInfo[i + j].Palette_Offset - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset == 0)
                pallength = offsets[j] - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset;
                Color[] c_ = nsbtx.PalInfo.infoBlock.PalInfo[i].pal;
                List<Color> c = new List<Color>();
                c.AddRange(nsbtx.PalInfo.infoBlock.PalInfo[i].pal.Take(pallength / 2));
                nsbtx.PalInfo.infoBlock.PalInfo[i].pal = c.ToArray();
            }
            er.Close();
            listBox5.SelectedIndex = 0;
            if (nsbtx.PalInfo.num_objs != 0)
            {
                listBox4.SelectedIndex = 0;
            }
        }
Exemple #15
0
        /// <summary>
        /// genAIS command.  Always use section-by-section CRC checks
        /// </summary>
        /// <param name="mainObjectFileName"></param>
        /// <param name="bootMode"></param>
        /// <returns>Bytes of the binary or text AIS command</returns>
        public static Byte[] GenAIS( AISGen devAISGen, 
                                 List<String> inputFileNames,
                                 IniFile iniFile )
        {
            UInt32 numWords;

              // Setup the binary writer to generate the temp AIS file
              devAISGen.devAISStream = new MemoryStream();
              using ( devAISGen.writer = new EndianBinaryWriter( devAISGen.devAISStream, devAISGen.devEndian) )
              {
            // List to keep track of loadable sections and their occupied memory ranges
            devAISGen.sectionMemory = new List<MemoryRange>();
            // Initiate list to keep track of the input files
            devAISGen.objectFiles   = new List<ObjectFile>();

            // Get data from the GENERAL INI Section
            GeneralIniSectionParse(devAISGen, iniFile);

            #region Main AIS Generation
            // ---------------------------------------------------------
            // ****************** BEGIN AIS GENERATION *****************
            // ---------------------------------------------------------
            Console.WriteLine("Begining the AIS file generation.");

            // Diaplay currently selected boot mode
            Console.WriteLine("AIS file being generated for bootmode: {0}.",Enum.GetName(typeof(AisBootModes),devAISGen.bootMode));

            // Write the premilinary header and fields (everything before first AIS command)
            devAISGen.InsertAISPreamble();
            Debug.DebugMSG("Preamble Complete");

            // Parse the INI sections in order, inserting needed AIS commands
            if (iniFile != null)
            {
              foreach(IniSection sec in iniFile.Sections)
              {
            InsertAISCommandViaINI(devAISGen, sec);
              }
              Debug.DebugMSG("INI parsing complete");
            }

            // Insert the object file passed in on the top-level (if it exists)
            if (inputFileNames != null)
            {
              foreach (String fn in inputFileNames)
              {
            String[] nameAndAddr = fn.Split('@');

            Debug.DebugMSG("Inserting file " + nameAndAddr[0]);

            if (!File.Exists(nameAndAddr[0]))
            {
              Console.WriteLine("ERROR: {0} does not exist. Aborting...", nameAndAddr[0]);
              return null;
            }

            if (nameAndAddr.Length == 2)
            {
              UInt32 loadAddr;

              nameAndAddr[1] = nameAndAddr[1].ToLower();

              if (nameAndAddr[1].StartsWith("0x"))
              {
                if (!UInt32.TryParse(nameAndAddr[1].Replace("0x", ""), NumberStyles.HexNumber, null, out loadAddr))
                {
                  Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
                }
                else
                {
                  devAISGen.InsertAISObjectFile(nameAndAddr[0], loadAddr);
                }
              }
              else if (UInt32.TryParse(nameAndAddr[1], out loadAddr))
              {
                devAISGen.InsertAISObjectFile(nameAndAddr[0], loadAddr);
              }
              else
              {
                Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
              }
            }
            else if (nameAndAddr.Length == 1)
            {
              // If we still have not had a valid entry point set, then use entry point from
              // first encountered non-binary file in the inputFileNames list
              if (devAISGen.entryPoint == 0xFFFFFFFF)
              {
                devAISGen.InsertAISObjectFile(nameAndAddr[0], true);
              }
              else
              {
                devAISGen.InsertAISObjectFile(nameAndAddr[0], false);
              }
            }
            else
            {
              Console.WriteLine("WARNING: Invalid filename format, {0}. Ignoring...", fn);
            }
              }

              Debug.DebugMSG("Main input file insertion complete.");
            }

            // If CRC type is for single CRC, send Request CRC now
            if (devAISGen.aisCRCType == AisCRCCheckType.SINGLE_CRC)
            {
              devAISGen.InsertAISRequestCRC();
            }

            // Insert closing JumpClose AIS command (issue warning)
            if (devAISGen.entryPoint == 0xFFFFFFFF)
            {
              // No valid entry point was ever set (issue warning)
              Console.WriteLine("WARNING: Entry point set to null pointer!");
              devAISGen.InsertAISJumpClose(0x00000000);
            }
            else
            {
              devAISGen.InsertAISJumpClose(devAISGen.entryPoint);
            }

            // Flush the data and then return to start
            devAISGen.devAISStream.Flush();
            devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

            Console.WriteLine("AIS file generation was successful.");
            // ---------------------------------------------------------
            // ******************* END AIS GENERATION ******************
            // ---------------------------------------------------------

              #endregion

            // Now create return Byte array based on tempAIS file and the bootmode
            EndianBinaryReader tempAIS_br = new EndianBinaryReader(devAISGen.devAISStream, Endian.LittleEndian);

            // Setup the binary reader object
            numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
            devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes

            Debug.DebugMSG("Number of words in the AIS output is {0}", numWords);

            // Copy the data to the output Byte array
            for (UInt32 i = 0; i < numWords; i++)
            {
              BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
            }

            // Close the binary reader
            tempAIS_br.Close();
              }

              // Dispose of all object files
              foreach (ObjectFile file in devAISGen.objectFiles)
              {
            try
            {
              file.Dispose();
            }
            catch (Exception e)
            {
              Console.WriteLine(e.Message);
            }
              }

              // Clean up any embedded file resources that may have been extracted
              EmbeddedFileIO.CleanUpEmbeddedFiles();

              // Return Byte Array
              return devAISGen.AISData;
        }
        /// <summary>
        /// SecureGenAIS command.
        /// </summary>
        /// <param name="inputFileNames">File name of input .out file</param>
        /// <param name="bootMode">AISGen Object for the particular device</param>
        /// <returns>Bytes of the binary or AIS boot image</returns>
        public static Byte[] SecureGenAIS(AISGen devAISGen,
                                      List<String> inputFileNames,
                                      IniFile iniFile)
        {
            UInt32 numWords;

              // Set defaults
              devAISGen.bootLoaderExitType      = BootLoaderExitType.NONE;
              devAISGen.currHashAlgorithmValue  = SHA_Algorithm.SHA1;
              devAISGen.sectionsToEncrypt       = null;
              devAISGen.rsaObject               = null;
              devAISGen.customerEncryptionKey   = null;
              devAISGen.keyEncryptionKey        = null;
              devAISGen.genericKeyHeaderData    = null;
              devAISGen.currHashAlgorithm       = null;

              // Setup the binary writer to generate the temp AIS file
              devAISGen.sigStream       = new MemoryStream();
              devAISGen.devAISStream    = new MemoryStream();
              devAISGen.sigWriter       = new EndianBinaryWriter( devAISGen.sigStream, devAISGen.devEndian);
              using ( devAISGen.writer  = new EndianBinaryWriter( devAISGen.devAISStream, devAISGen.devEndian) )
              {
            // List to keep track of loadable sections and their occupied memory ranges
            devAISGen.sectionMemory = new List<MemoryRange>();
            // Initiate list to keep track of the input files
            devAISGen.objectFiles   = new List<ObjectFile>();

            // Get data from the GENERAL INI Section
            GeneralIniSectionParse(devAISGen, iniFile);

            // Get data from the SECURITY INI Section
            if (SecurityIniSectionParse(devAISGen, iniFile) != retType.SUCCESS)
            {
              Console.WriteLine("Aborting...");
              return null;
            }

              #region Handle the case of Legacy boot mode
            if (devAISGen.bootMode == AisBootModes.LEGACY)
            {
              UInt32 fileSize = 0, secureDataSize = 0, totalImgSize = 0, paddingSize = 0;
              UInt32 loadAddr = 0, fileCount = 0;
              Byte[] fileData;

              String fileName = null;
              Boolean encryptSections = false;
              UInt32 entryPointAddr = 0x00000000;

              // Check for legacy input file
              foreach( IniSection sec in iniFile.Sections)
              {
            if (sec.sectionName.Equals("LEGACYINPUTFILE", StringComparison.OrdinalIgnoreCase))
            {
              fileCount++;
              foreach (DictionaryEntry de in sec.sectionValues)
              {
                // File name for binary section data
                if (((String)de.Key).Equals("FILENAME", StringComparison.OrdinalIgnoreCase))
                {
                   fileName = (String) sec.sectionValues["FILENAME"];
                }

                // Binary section's load address in the memory map
                if (((String)de.Key).Equals("LOADADDRESS", StringComparison.OrdinalIgnoreCase))
                {
                  loadAddr = (UInt32) sec.sectionValues["LOADADDRESS"];
                }

                // Binary section's entry point address in the memory map
                if (((String)de.Key).Equals("ENTRYPOINTADDRESS", StringComparison.OrdinalIgnoreCase))
                {
                  entryPointAddr = (UInt32) sec.sectionValues["ENTRYPOINTADDRESS"];
                }

                // Binary section's entry point address in the memory map
                if (((String)de.Key).Equals("ENCRYPT", StringComparison.OrdinalIgnoreCase))
                {
                  if (((String)sec.sectionValues["ENCRYPT"]).Equals("YES", StringComparison.OrdinalIgnoreCase))
                    encryptSections = true;
                  if (((String)sec.sectionValues["ENCRYPT"]).Equals("TRUE", StringComparison.OrdinalIgnoreCase))
                    encryptSections = true;
                }

              }

              if (fileName == null)
              {
                Console.WriteLine("ERROR: File name must be provided in INPUTFILE section.");
                return null;
              }

              // Insert the file into the AIS image
              if (( entryPointAddr == 0x00000000))
              {
                Console.WriteLine("Entrypoint Address = {0} is not valid.", entryPointAddr);
                return null;
              }
            }
              }

              // Validate an input binary file was given in the INI file
              if (fileCount == 0)
              {
            Console.WriteLine("ERROR: You did not supply a binary file section in the INI file!");
            return null;
              }
              if (fileCount > 1)
              {
            Console.WriteLine("WARNING: You supplied too many binary file sections in the INI file.");
            Console.WriteLine("         Only using the first one.");
              }

              // Figure out the size of the secure data region (signature + keystruct)
              if (devAISGen.SecureType == AisSecureType.CUSTOM)
              {
            // On custom secure we have rsa keySize bits for signature and modulus of key struct,
            // plus eight additional bytes from key struct
            secureDataSize = (UInt32) (8 + (devAISGen.rsaObject.KeySize >> 3) + (devAISGen.rsaObject.KeySize >> 3));
              }
              else if (devAISGen.SecureType == AisSecureType.GENERIC)
              {
            // On generic secure we have 32 for key and HashSize bits rounded up to nearst 16 bytes
            // for signature data.
            secureDataSize = (UInt32) (32 + ((((devAISGen.currHashAlgorithm.HashSize >> 3)+15)>>4)<<4));
              }

              // Verify legacy input binary file exists, and get data if it does
              if (File.Exists(fileName))
              {
            Byte[] tempFileData = FileIO.GetFileData(fileName);

            fileSize = (UInt32) tempFileData.Length;

            totalImgSize = 16 + fileSize + secureDataSize;

            if (totalImgSize > 16*1024)
            {
              Console.WriteLine("WARNING: The input image is too large for the ROM boot loader.");
              Console.WriteLine("Reduce its size by {0} bytes.", (totalImgSize - (16*1024)));
            }

            // Figure out how much to pad input file region to acheive complete image ending on 1K boundary
            paddingSize = (((totalImgSize+1023) >> 10) << 10) - totalImgSize;

            // Copy to final data array of fileSize
            fileSize = fileSize + paddingSize;
            fileData = new Byte[fileSize];
            tempFileData.CopyTo(fileData,0);

            // Adjust total image size to final amount
            totalImgSize = 16 + fileSize + secureDataSize;
              }
              else
              {
            Console.WriteLine("Error: Binary file was not found!");
            return null;
              }

              if ( ((entryPointAddr & 0x00FFFFFF) < loadAddr) ||
               ((entryPointAddr & 0x00FFFFFF) > (loadAddr+fileSize)) )
              {
            Console.WriteLine("ERROR: Entry point falls outside load image region.");
            return null;
              }

              // Place header
              // Config Word - indicates total image size, nor width (if applicable)
              if (devAISGen.busWidth == 16)
              {
            devAISGen.writer.Write   ((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x1 << 0)|(0x0 << 4)));
            devAISGen.sigWriter.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x1 << 0)|(0x0 << 4)));
              }
              else
              {
            devAISGen.writer.Write   ((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x0 << 0)|(0x0 << 4)));
            devAISGen.sigWriter.Write((UInt32)(((((totalImgSize >> 10)-1) & 0xFFFF) << 8)|(0x0 << 0)|(0x0 << 4)));
              }

              // Magic Number   - indicates signed or encrypted
              if (encryptSections)
              {
            devAISGen.writer.Write((UInt32)SecureLegacyMagic.ENCMOD_MAGIC);
            devAISGen.sigWriter.Write((UInt32)SecureLegacyMagic.ENCMOD_MAGIC);
              }
              else
              {
            devAISGen.writer.Write((UInt32)SecureLegacyMagic.SIGNMOD_MAGIC);
            devAISGen.sigWriter.Write((UInt32)SecureLegacyMagic.SIGNMOD_MAGIC);
              }

              // Entry Point - where to jump within the image upon load
              devAISGen.writer.Write( entryPointAddr );
              devAISGen.sigWriter.Write( entryPointAddr );

              // SecureDataSize - size of data following image for key struct & signature
              devAISGen.writer.Write( (UInt32)secureDataSize );
              devAISGen.sigWriter.Write( (UInt32)secureDataSize );

              // Now place padded binary contents
              if (!encryptSections)
              {
            // Non-encrypted section
            devAISGen.writer.Write(fileData);
            devAISGen.sigWriter.Write(fileData);
              }
              else
              {
            // Encrypted section
            // Write unencrypted data to the signature buffer
            devAISGen.sigWriter.Write(fileData);

            // Encrypt data using CBC algorithm
            try
            {
              Byte[] encData = AesManagedUtil.AesCTSEncrypt(fileData,devAISGen.customerEncryptionKey,devAISGen.CEKInitialValue);

              // Write encrypted section data out to AIS data stream
              devAISGen.writer.Write(encData);
            }
            catch(Exception e)
            {
              Console.WriteLine("Exception during encryption operation: {0}",e.Message);
            }
              }

              // Now place the key data
              devAISGen.writer.Write(devAISGen.secureKeyData);
              devAISGen.sigWriter.Write(devAISGen.secureKeyData);

              // Finally place the signature which covers the entire image
              InsertAISSecureSignature( devAISGen );

              // Flush the data and then return to start
              devAISGen.devAISStream.Flush();
              devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

              devAISGen.sigStream.Close();
            }
              #endregion

              #region AIS Generation
            else
            {
              // ---------------------------------------------------------
              // ****************** BEGIN AIS GENERATION *****************
              // ---------------------------------------------------------
              Console.WriteLine("Begining the Secure AIS file generation.");

              // Diaplay currently selected boot mode
              Console.WriteLine("AIS file being generated for bootmode: {0}.",Enum.GetName(typeof(AisBootModes),devAISGen.bootMode));

              // Write the premilinary header and fields (everything before first AIS command)
              devAISGen.InsertAISPreamble();
              Debug.DebugMSG("Preamble Complete");

              // Write the Secure Key command and key data
              devAISGen.InsertAISSecureKeyLoad(devAISGen.secureKeyData);
              Debug.DebugMSG("Secure Key Insertion Complete");

              // Insert Exit Mode type
              devAISGen.InsertAISSetExitMode(devAISGen.bootLoaderExitType);
              Debug.DebugMSG("Set Exit Mode complete");

              // Parse the INI sections in order, inserting needed AIS commands
              foreach(IniSection sec in iniFile.Sections)
              {
            InsertSecureAISCommandViaINI(devAISGen, sec);
              }
              Debug.DebugMSG("INI parsing complete");

              // Insert the object file(s) passed in on the top-level (if it exists)
              foreach (String fn in inputFileNames)
              {
            String[] nameAndAddr = fn.Split('@');

            Debug.DebugMSG("Inserting file " + nameAndAddr[0]);

            if (!File.Exists(nameAndAddr[0]))
            {
              Console.WriteLine("ERROR: {0} does not exist. Aborting...", nameAndAddr[0]);
              return null;
            }

            // Handle binary files provided with a load address
            if (nameAndAddr.Length == 2)
            {
              UInt32 loadAddr;

              nameAndAddr[1] = nameAndAddr[1].ToLower();

              if (nameAndAddr[1].StartsWith("0x"))
              {
                if (!UInt32.TryParse(nameAndAddr[1].Replace("0x", ""), NumberStyles.HexNumber, null, out loadAddr))
                {
                  Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
                }
                else
                {
                  devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], loadAddr, false);
                }
              }
              else if (UInt32.TryParse(nameAndAddr[1], out loadAddr))
              {
                devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], loadAddr, false);
              }
              else
              {
                Console.WriteLine("WARNING: Invalid address format, {0}. Ignoring...", nameAndAddr[1]);
              }
            }

            // Handle Object files (ones provided without load address)
            else if (nameAndAddr.Length == 1)
            {
              // If we still have not had a valid entry point set, then use entry point from
              // first encountered non-binary file in the inputFileNames list
              if (devAISGen.entryPoint == 0xFFFFFFFF)
              {
                devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], true, false);
              }
              else
              {
                devAISGen.InsertAISSecureObjectFile(nameAndAddr[0], false, false);
              }
            }
            else
            {
              Console.WriteLine("WARNING: Invalid filename format, {0}. Ignoring...", fn);
            }
              }

              Debug.DebugMSG("Main input file insertion complete.");

              // Insert closing JumpClose AIS command (issue warning)
              if (devAISGen.entryPoint == 0x00000000)
              {
            Console.WriteLine("WARNING: Entry point set to null pointer!");
              }
              devAISGen.InsertAISJumpClose(devAISGen.entryPoint);

              // Insert final Signature
              InsertAISSecureSignature(devAISGen);

              // Flush the data and then return to start
              devAISGen.devAISStream.Flush();
              devAISGen.devAISStream.Seek(0,SeekOrigin.Begin);

              Console.WriteLine("AIS file generation was successful.");
              // ---------------------------------------------------------
              // ******************* END AIS GENERATION ******************
              // ---------------------------------------------------------
            }
              #endregion

            // Now create return byte array based on AIS Stream data
            EndianBinaryReader tempAIS_br = new EndianBinaryReader(devAISGen.devAISStream,Endian.LittleEndian);

            numWords = ((UInt32)tempAIS_br.BaseStream.Length) >> 2;
            devAISGen.AISData = new Byte[numWords << 2];   //Each word converts to 4 binary bytes

            Debug.DebugMSG("Number of words in the stream is {0}", numWords);

            // Copy the data to the output Byte array
            for (UInt32 i = 0; i < numWords; i++)
            {
              BitConverter.GetBytes(tempAIS_br.ReadUInt32()).CopyTo(devAISGen.AISData, i * 4);
            }

            // Close the binary reader
            tempAIS_br.Close();
              }

              // Dispose of all object files
              foreach (ObjectFile file in devAISGen.objectFiles)
              {
            try
            {
              file.Dispose();
            }
            catch (Exception e)
            {
              Console.WriteLine(e.Message);
            }
              }

              // Clean up any embedded file resources that may have been extracted
              EmbeddedFileIO.CleanUpEmbeddedFiles();

              // Return Byte Array
              return devAISGen.AISData;
        }