Exemplo n.º 1
0
Arquivo: track.go Projeto: silky/rct
// Parse the serialized data into a Element struct
// When the end of ride is encountered a EndOfRide error is returned
// Documentation from
// http://freerct.github.io/RCTTechDepot-Archive/trackQualifier.html
func unmarshalElement(rawElement []byte) (te Element, e error) {
	if len(rawElement) != 2 {
		return Element{}, errors.New("invalid length for element input")
	}
	// XXX hack for brakes
	if rawElement[0] == 0xd8 {
		rawElement[0] = ELEM_BRAKES
	}
	te.Segment = TS_MAP[SegmentType(rawElement[0])]
	if te.Segment.Type == ELEM_END_OF_RIDE {
		return Element{}, EndOfRide
	}
	q := int(rawElement[1])
	te.ChainLift = bits.On(q, 7)
	te.InvertedTrack = bits.On(q, 6)
	te.Station = bits.On(q, 3)
	if te.Station {
		fmt.Println("found station piece")
		fmt.Println(te.Segment)
	}
	te.StationNumber = q & 3

	te.BoostMagnitude = float32(q&15) * 7.6
	te.Rotation = (q&15)*45 - 180
	return
}
Exemplo n.º 2
0
// XXX, this doesn't correctly handle s-bends, which only move sideways by 1
// piece, I think.
func SidewaysDelta(sidewaysDeltaByte int) int {
	if sidewaysDeltaByte == 0 {
		return 0
	}
	if bits.On(sidewaysDeltaByte, 7) {
		return 1 + (256-sidewaysDeltaByte)>>5
	}
	return -(1 + sidewaysDeltaByte>>5)
}
Exemplo n.º 3
0
func testMarshalControlFlags(t *testing.T) {
	t.Parallel()
	cFlags := ControlFlags{
		Load:           3,
		UseMaximumTime: true,
	}
	n := marshalControlFlags(cFlags)
	if !bits.On(n, 7) {
		t.Errorf("Maximum time bit should have been set, but wasn't, n is %d", n)
	}
}
Exemplo n.º 4
0
Arquivo: egress.go Projeto: silky/rct
// Get list of entrances/exits for a ride from raw data
// Copied mostly from "Scenery Items" here:
// http://freerct.github.io/RCTTechDepot-Archive/TD6.html
func unmarshalEgress(buf []byte) []*Egress {
	var egrs []*Egress
	for i := 0; true; i += 6 {
		if buf[i] == 0xff {
			break
		}
		features := int(buf[i+1])
		egr := &Egress{
			Exit: bits.On(features, 7),
			// Direction set in lower two bits
			Direction: features & 3,
			XOffset:   int16(binary.LittleEndian.Uint16(buf[i+2 : i+4])),
			YOffset:   int16(binary.LittleEndian.Uint16(buf[i+4 : i+6])),
		}
		egrs = append(egrs, egr)
	}
	return egrs
}
Exemplo n.º 5
0
Arquivo: td4.go Projeto: silky/rct
func hasBit(n int, pos uint) bool {
	return bits.On(n, pos)
}
Exemplo n.º 6
0
func hasLoop(n int) bool {
	return bits.On(n, BIT_VERTICAL_LOOP)
}
Exemplo n.º 7
0
Arquivo: lib.go Projeto: silky/rct
// Take a compressed byte stream representing a ride and turn it into a Ride
// struct. Returns an error if the byte array is too short.
func Unmarshal(buf []byte, r *Ride) error {
	if len(buf) < IDX_TRACK_DATA {
		return errors.New("buffer too short to be a ride")
	}
	r.RideType = RideType(buf[IDX_RIDE_TYPE])

	featuresBit0 := int(buf[IDX_FEATURES_0])
	r.SteepLiftChain = bits.On(featuresBit0, BIT_STEEP_LIFT_CHAIN)
	r.CurvedLiftChain = bits.On(featuresBit0, BIT_CURVED_LIFT_CHAIN)
	r.Banking = bits.On(featuresBit0, BIT_BANKING)
	r.HasLoop = bits.On(featuresBit0, BIT_VERTICAL_LOOP)

	featuresBit1 := int(buf[IDX_FEATURES_1])
	r.SteepSlope = bits.On(featuresBit1, BIT_STEEP_SLOPE)
	r.FlatToSteep = bits.On(featuresBit1, BIT_FLAT_TO_STEEP)
	r.SlopedCurves = bits.On(featuresBit1, BIT_SLOPED_CURVES)
	r.SteepTwist = bits.On(featuresBit1, BIT_STEEP_TWIST)
	r.SBends = bits.On(featuresBit1, BIT_S_BENDS)
	r.SmallRadiusCurves = bits.On(featuresBit1, BIT_SMALL_RADIUS_CURVES)
	r.SmallRadiusBanked = bits.On(featuresBit1, BIT_SMALL_RADIUS_BANKED)

	r.OperatingMode = OperatingMode(buf[IDX_OPERATING_MODE])
	r.ControlFlags = unmarshalControlFlags(int(buf[IDX_CONTROL_FLAG]))
	r.NumTrains = uint8(buf[IDX_NUM_TRAINS])
	r.CarsPerTrain = uint8(buf[IDX_CARS_PER_TRAIN])
	r.MinWaitTime = uint8(buf[IDX_MIN_WAIT_TIME])
	r.MaxWaitTime = uint8(buf[IDX_MAX_WAIT_TIME])
	r.NumInversions = uint8(buf[IDX_NUM_INVERSIONS])
	r.MaxSpeed = uint8(buf[IDX_MAX_SPEED])
	r.AverageSpeed = uint8(buf[IDX_AVERAGE_SPEED])

	d := new(tracks.Data)
	tracks.Unmarshal(buf[IDX_TRACK_DATA:], d)
	r.TrackData = *d

	r.VehicleType = VehicleType(string(buf[IDX_VEHICLE_TYPE_STRING : IDX_VEHICLE_TYPE_STRING+LENGTH_VEHICLE_TYPE]))

	r.XSpaceRequired = int(buf[IDX_X_SPACE])
	r.YSpaceRequired = int(buf[IDX_Y_SPACE])

	r.DatData = buf[0x70:0x80]

	// XXX, not sure if this fn should know about this, or the track data
	entranceExitIdx := IDX_TRACK_DATA + 2*len(r.TrackData.Elements) + 1
	r.Egresses = unmarshalEgress(buf[entranceExitIdx:])

	r.Excitement = int16(buf[IDX_EXCITEMENT])
	r.Intensity = int16(buf[IDX_INTENSITY])
	r.Nausea = int16(buf[IDX_NAUSEA])

	// Ignore scenery data for now.
	// sceneryIdx := entranceExitIdx + 6*len(r.Egresses) + 1

	return nil
}