public static byte[] Marshal(TrackElement e) { byte[] buf = new byte[2]; buf[0] = (byte)e.Segment.Type; int featureBit = 0; featureBit = BitOp.SetCond(featureBit, 7, e.ChainLift); featureBit = BitOp.SetCond(featureBit, 6, e.InvertedTrack); featureBit = BitOp.SetCond(featureBit, 3, e.Station); if (e.Segment.Type == SegmentType.ELEM_END_STATION || e.Segment.Type == SegmentType.ELEM_BEGIN_STATION || e.Segment.Type == SegmentType.ELEM_MIDDLE_STATION) { // Set the station bit featureBit |= e.StationNumber; } // XXX booster? if (e.Segment.Type == SegmentType.ELEM_BRAKES || e.Segment.Type == SegmentType.ELEM_BLOCK_BRAKES) { float bm = (float)(e.BoostMagnitude / 7.6); featureBit |= (int)bm; } else { // 2nd bit seems to be set in most cases. featureBit |= 1 << 2; } // XXX, rotation for multi dimensional coasters buf[1] = (byte)featureBit; return buf; }
public static TrackElement Unmarshal(byte[] rawElement) { if (rawElement.Length != 2) { throw new Exception("Invalid length for element input"); } // XXX hack for brakes if (rawElement[0] == 0xd8) { rawElement[0] = (byte)SegmentType.ELEM_BRAKES; } TrackElement te = new TrackElement(); te.Segment = Track.TrackSegmentMap[(SegmentType)rawElement[0]]; if (te.Segment.Type == SegmentType.ELEM_END_OF_RIDE) return te; int q = (int)rawElement[1]; te.ChainLift = BitOp.On(q, 7); te.InvertedTrack = BitOp.On(q, 6); te.Station = BitOp.On(q, 3); #if DEBUG if (te.Station) { Console.WriteLine("found station piece"); Console.WriteLine(te.Segment); } #endif te.StationNumber = q & 3; te.BoostMagnitude = (float)(q & 15) * (float)7.6; te.Rotation = (q & 15) * 45 - 180; return te; }