/* Copyright 2012 Cedric Van Goethem This file is part of AbState Editor. AbState Editor is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. AbState Editor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see http://www.gnu.org/licenses/. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; namespace ActionReader { sealed class ActionFile { public List Blocks = new List(); public ActionFile(string path) { BinaryReader reader = new BinaryReader(File.Open(path, FileMode.Open)); int count = reader.ReadInt32(); for (int i = 0; i < count; ++i) { ActionBlock block = new ActionBlock(); block.ActID = reader.ReadInt16(); block.SHNPath = ReadString(reader, 0x21); block.FilePath = ReadString(reader, 0x21); reader.ReadInt32(); // -1 block.Text = ReadString(reader, 0x24); block.NifAnimID = reader.ReadInt32(); //animID reader.ReadInt32(); //zeros block.s1 = ReadWeirdBlock(reader, 33); block.s2 = ReadWeirdBlock(reader, 33); block.s3 = ReadWeirdBlock(reader, 34); block.something = reader.ReadBytes(0x30); block.Sound1 = ReadWeirdBlock(reader, 33); block.Sound2 = ReadWeirdBlock(reader, 35); block.Signature = reader.ReadInt32(); block.somthingelse = reader.ReadBytes(0x10); Blocks.Add(block); } reader.Close(); } public void Save(string path) { BinaryWriter writer = new BinaryWriter(File.Create(path)); writer.Write((int)Blocks.Count); foreach(var block in Blocks){ writer.Write((short)block.ActID); WriteString(block.SHNPath, 0x21, writer); WriteString(block.FilePath, 0x21, writer); writer.Write((int)-1); WriteString(block.Text, 0x24, writer); writer.Write((int)block.NifAnimID); writer.Write((int)0); WriteWeirdString(block.s1, 33, writer); WriteWeirdString(block.s2, 33, writer); WriteWeirdString(block.s3, 34, writer); if (block.something != null) { writer.Write(block.something); } else { for (int i = 0; i < 0x30; ++i) writer.Write((byte)0); } WriteWeirdString(block.Sound1, 33, writer); WriteWeirdString(block.Sound2, 35, writer); writer.Write((int)block.Signature); if (block.something != null) { writer.Write(block.somthingelse); } else { for (int i = 0; i < 0x10; ++i) writer.Write((byte)0); } } writer.Close(); } private void WriteWeirdString(string str, int len, BinaryWriter writer) { if (str == "Empty") str = ""; if (str != "") { // writer.Write((short)str.Length); WriteString(str, len, writer); } else { writer.Write((short)45); for (int i = 0; i < (len - 2); ++i) writer.Write((byte)0xcd); } } private void WriteString(string str, int len, BinaryWriter writer) { if (str == "Empty") str = ""; if (str.Length > len) throw new Exception("String lenght to big for this block! str=" + str); foreach (char c in str) writer.Write(c); writer.Write((byte)0); for (int i = 0; i < (len - @str.Length - 1); i++) writer.Write((byte)0xCD); } private string ReadWeirdBlock(BinaryReader reader, int len) { short fock = reader.ReadInt16(); if (fock != 45) { reader.BaseStream.Position -= 2; return ReadString(reader, len); } else { //45 means empty return ReadString(reader, len - 2); } } string ReadString(BinaryReader reader, int len) { byte[] dat = reader.ReadBytes(len); int realLen = 0; for (int i = 0; i < len; i++) { if (dat[i] == 0) { realLen = i; break; } } if (realLen == 0) return "Empty"; else return System.Text.Encoding.ASCII.GetString(dat, 0, realLen); } } public sealed class ActionBlock : ListViewItem { public string SHNPath { get; set; } public string FilePath { get; set; } public int NifAnimID { get; set; } public short ActID { get; set; } // public string ActName { get; set; } public string s1 { get; set; } public string s2 { get; set; } public string s3 { get; set; } public byte[] something { get; set; } public string Sound1 { get; set; } public string Sound2 { get; set; } public int Signature { get; set; } public byte[] somthingelse { get; set; } } }