first commit
This commit is contained in:
81
Core/TASFile.cs
Normal file
81
Core/TASFile.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BallanceTASEditor.Core {
|
||||
public class TASFile {
|
||||
public TASFile(string filename) {
|
||||
mFilename = filename;
|
||||
mMem = new LinkedList<FrameData>();
|
||||
var fs = new FileStream(mFilename, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
ZlibUtil.DecompressTAS(mMem, fs);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
mPointer = mMem.First;
|
||||
}
|
||||
|
||||
public string mFilename { get; private set; }
|
||||
public long mFrameCount { get { return mMem.Count; } }
|
||||
LinkedList<FrameData> mMem;
|
||||
LinkedListNode<FrameData> mPointer;
|
||||
|
||||
public void Shift(long shiftNum) {
|
||||
if (mPointer == null) return;
|
||||
if (shiftNum == 0) return;
|
||||
var absNum = Math.Abs(shiftNum);
|
||||
if (shiftNum > 0) {
|
||||
for(long num = 0; num < absNum && mPointer.Next != null; num++) {
|
||||
mPointer = mPointer.Next;
|
||||
}
|
||||
} else {
|
||||
for (long num = 0; num < absNum && mPointer.Previous != null; num++) {
|
||||
mPointer = mPointer.Previous;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Get(ObservableCollection<FrameDataDisplay> container, long startIndex, int count) {
|
||||
if (mPointer == null) return 0;
|
||||
var cachePointer = mPointer;
|
||||
int i;
|
||||
for(i = 0; i < count && cachePointer != null; i++, startIndex++) {
|
||||
container[i].Reload(startIndex, cachePointer.Value);
|
||||
cachePointer = cachePointer.Next;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public void Set(FrameDataField field, long prevRange, long nextRange, bool isSet) {
|
||||
if (mPointer == null) return;
|
||||
|
||||
var cachePointer = mPointer;
|
||||
var offset = ConstValue.Mapping[field];
|
||||
for (long i = 0; i < nextRange && cachePointer != null; i++) {
|
||||
if (isSet) cachePointer.Value.SetKeyStates(offset);
|
||||
else cachePointer.Value.UnsetKeyStates(offset);
|
||||
cachePointer = cachePointer.Next;
|
||||
}
|
||||
for (long i = 0; i < prevRange && cachePointer != null; i++) {
|
||||
if (isSet) cachePointer.Value.SetKeyStates(offset);
|
||||
else cachePointer.Value.UnsetKeyStates(offset);
|
||||
cachePointer = cachePointer.Previous;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save() {
|
||||
var fs = new FileStream(mFilename, FileMode.Create, FileAccess.Write, FileShare.None);
|
||||
ZlibUtil.CompressTAS(mMem, fs);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
|
||||
public void SaveAs(string newfile) {
|
||||
mFilename = newfile;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
144
Core/TASStruct.cs
Normal file
144
Core/TASStruct.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BallanceTASEditor.Core.TASStruct {
|
||||
public class FrameDataDisplay : INotifyPropertyChanged {
|
||||
public FrameDataDisplay(long index, FrameData fd) {
|
||||
Reload(index, fd);
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
private void OnPropertyChanged(String propertyName) {
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
public void Reload(long index, FrameData fd) {
|
||||
this.index = index;
|
||||
this.deltaTime = fd.deltaTime;
|
||||
|
||||
OnPropertyChanged("index");
|
||||
OnPropertyChanged("deltaTime");
|
||||
|
||||
this.keystates = fd.keystates;
|
||||
}
|
||||
|
||||
public long index { get; set; }
|
||||
public float deltaTime { get; set; }
|
||||
public UInt32 keystates {
|
||||
get {
|
||||
UInt32 result = 0;
|
||||
if (key_enter) result |= 1; result <<= 1;
|
||||
if (key_esc) result |= 1; result <<= 1;
|
||||
if (key_q) result |= 1; result <<= 1;
|
||||
if (key_space) result |= 1; result <<= 1;
|
||||
if (key_shift) result |= 1; result <<= 1;
|
||||
if (key_right) result |= 1; result <<= 1;
|
||||
if (key_left) result |= 1; result <<= 1;
|
||||
if (key_down) result |= 1; result <<= 1;
|
||||
if (key_up) result |= 1; result <<= 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
set {
|
||||
key_up = (value & (1 << 0)).ToBool();
|
||||
key_down = (value & (1 << 1)).ToBool();
|
||||
key_left = (value & (1 << 2)).ToBool();
|
||||
key_right = (value & (1 << 3)).ToBool();
|
||||
key_shift = (value & (1 << 4)).ToBool();
|
||||
key_space = (value & (1 << 5)).ToBool();
|
||||
key_q = (value & (1 << 6)).ToBool();
|
||||
key_esc = (value & (1 << 7)).ToBool();
|
||||
key_enter = (value & (1 << 8)).ToBool();
|
||||
|
||||
OnPropertyChanged("key_up");
|
||||
OnPropertyChanged("key_down");
|
||||
OnPropertyChanged("key_left");
|
||||
OnPropertyChanged("key_right");
|
||||
OnPropertyChanged("key_shift");
|
||||
OnPropertyChanged("key_space");
|
||||
OnPropertyChanged("key_q");
|
||||
OnPropertyChanged("key_esc");
|
||||
OnPropertyChanged("key_enter");
|
||||
}
|
||||
}
|
||||
public bool key_up { get; set; }
|
||||
public bool key_down { get; set; }
|
||||
public bool key_left { get; set; }
|
||||
public bool key_right { get; set; }
|
||||
public bool key_shift { get; set; }
|
||||
public bool key_space { get; set; }
|
||||
public bool key_q { get; set; }
|
||||
public bool key_esc { get; set; }
|
||||
public bool key_enter { get; set; }
|
||||
}
|
||||
|
||||
public class FrameData {
|
||||
|
||||
public FrameData(Stream st) {
|
||||
var temp = new byte[ConstValue.FRAMEDATA_SIZE];
|
||||
st.Read(temp, 0, ConstValue.FRAMEDATA_SIZE);
|
||||
|
||||
deltaTime = BitConverter.ToSingle(temp, ConstValue.FRAMEDATA_OFFSET_DELTATIME);
|
||||
keystates = BitConverter.ToUInt32(temp, ConstValue.FRAMEDATA_OFFSET_KEY_STATES);
|
||||
}
|
||||
public FrameData(FrameDataDisplay fdd) {
|
||||
this.deltaTime = fdd.deltaTime;
|
||||
this.keystates = fdd.keystates;
|
||||
}
|
||||
|
||||
public FrameData() {
|
||||
this.deltaTime = 0f;
|
||||
this.keystates = 0;
|
||||
}
|
||||
|
||||
public FrameData(float d, UInt32 k) {
|
||||
this.deltaTime = d;
|
||||
this.keystates = k;
|
||||
}
|
||||
|
||||
public void SetKeyStates(UInt32 offset) {
|
||||
keystates |= offset;
|
||||
}
|
||||
|
||||
public void UnsetKeyStates(UInt32 offset) {
|
||||
keystates &= ~offset;
|
||||
}
|
||||
|
||||
public float deltaTime;
|
||||
public UInt32 keystates;
|
||||
}
|
||||
|
||||
public class ConstValue {
|
||||
public static readonly Dictionary<FrameDataField, UInt32> Mapping = new Dictionary<FrameDataField, UInt32>() {
|
||||
{FrameDataField.Key_Up, (1 << 0)},
|
||||
{FrameDataField.Key_Down, (1 << 1)},
|
||||
{FrameDataField.Key_Left, (1 << 2)},
|
||||
{FrameDataField.Key_Right, (1 << 3)},
|
||||
{FrameDataField.Key_Shift, (1 << 4)},
|
||||
{FrameDataField.Key_Space, (1 << 5)},
|
||||
{FrameDataField.Key_Q, (1 << 6)},
|
||||
{FrameDataField.Key_Esc, (1 << 7)},
|
||||
{FrameDataField.Key_Enter, (1 << 8)}
|
||||
};
|
||||
public const int FRAMEDATA_SIZE = 8;
|
||||
public const int FRAMEDATA_OFFSET_DELTATIME = 0;
|
||||
public const int FRAMEDATA_OFFSET_KEY_STATES = 4;
|
||||
}
|
||||
|
||||
public enum FrameDataField {
|
||||
Key_Up,
|
||||
Key_Down,
|
||||
Key_Left,
|
||||
Key_Right,
|
||||
Key_Shift,
|
||||
Key_Space,
|
||||
Key_Q,
|
||||
Key_Esc,
|
||||
Key_Enter
|
||||
}
|
||||
|
||||
}
|
||||
22
Core/Util.cs
Normal file
22
Core/Util.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BallanceTASEditor.Core {
|
||||
public static class Util {
|
||||
public static bool ToBool(this UInt32 num) {
|
||||
return (num != 0);
|
||||
}
|
||||
public static UInt32 ToUInt32(this bool b) {
|
||||
return (UInt32)(b ? 1 : 0);
|
||||
}
|
||||
//public static void RemoveRange(this ModifiedObservableCollection<FrameData> list, int index, int count) {
|
||||
// if (index >= list.Count) return;
|
||||
// if (index + count > list.Count) count = list.Count - index;
|
||||
// for (int i = 0; i < count; i++) list.RemoveAt(index);
|
||||
//}
|
||||
}
|
||||
}
|
||||
55
Core/ZlibUtil.cs
Normal file
55
Core/ZlibUtil.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using BallanceTASEditor.Core.TASStruct;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace BallanceTASEditor.Core {
|
||||
public class ZlibUtil {
|
||||
private const int COPY_STREAM_UNIT = 1024;
|
||||
|
||||
public static void CompressTAS(LinkedList<FrameData> mem, FileStream file) {
|
||||
file.Write(BitConverter.GetBytes(mem.Count * ConstValue.FRAMEDATA_SIZE), 0, 4);
|
||||
|
||||
var zo = new zlib.ZOutputStream(file, 9);
|
||||
var node = mem.First;
|
||||
while (node != null) {
|
||||
zo.Write(BitConverter.GetBytes(node.Value.deltaTime), 0, 4);
|
||||
zo.Write(BitConverter.GetBytes(node.Value.keystates), 0, 4);
|
||||
node = node.Next;
|
||||
}
|
||||
zo.finish();
|
||||
zo.Close();
|
||||
}
|
||||
|
||||
public static void DecompressTAS(LinkedList<FrameData> ls, FileStream file) {
|
||||
var lengthTemp = new byte[4];
|
||||
var mem = new MemoryStream();
|
||||
file.Read(lengthTemp, 0, 4);
|
||||
Int32 expectedLength = BitConverter.ToInt32(lengthTemp, 0);
|
||||
long expectedCount = expectedLength / ConstValue.FRAMEDATA_SIZE;
|
||||
|
||||
var zo = new zlib.ZOutputStream(mem);
|
||||
CopyStream(file, zo);
|
||||
zo.finish();
|
||||
|
||||
mem.Seek(0, SeekOrigin.Begin);
|
||||
for(long i = 0; i < expectedCount; i++) {
|
||||
ls.AddLast(new FrameData(mem));
|
||||
}
|
||||
mem.Close();
|
||||
zo.Close();
|
||||
}
|
||||
|
||||
public static void CopyStream(Stream origin, Stream target) {
|
||||
var buffer = new byte[COPY_STREAM_UNIT];
|
||||
int len;
|
||||
while ((len = origin.Read(buffer, 0, COPY_STREAM_UNIT)) > 0) {
|
||||
target.Write(buffer, 0, len);
|
||||
}
|
||||
//target.Flush();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user