2020-07-02 17:26:19 +00:00
|
|
|
package tf.bug.fancadescodec
|
|
|
|
|
|
|
|
import scodec._
|
|
|
|
import scodec.bits.{BitVector, ByteVector}
|
|
|
|
import scodec.codecs._
|
|
|
|
|
|
|
|
object Codecs {
|
|
|
|
|
|
|
|
lazy val low: Codec[Unit] = constant(BitVector.low(1L))
|
|
|
|
lazy val high: Codec[Unit] = constant(BitVector.high(1L))
|
|
|
|
|
|
|
|
def optionC[A](b: Boolean, c: Codec[A]): Codec[Option[A]] =
|
|
|
|
optional(provide(b), c)
|
|
|
|
|
|
|
|
lazy val fancadeString: Codec[String] = variableSizeBytes(uint8L, utf8)
|
|
|
|
|
|
|
|
lazy val cartridgeMagic: Codec[Unit] = constant(ByteVector(0x1B, 0x00))
|
|
|
|
lazy val entriesMagic: Codec[Unit] = constant(ByteVector(0x2C, 0x02))
|
|
|
|
|
|
|
|
lazy val cartridge: Codec[Cartridge] =
|
|
|
|
(
|
|
|
|
cartridgeMagic ~>
|
|
|
|
fancadeString ::
|
|
|
|
fancadeString ::
|
|
|
|
fancadeString ::
|
|
|
|
(entriesMagic ~> vectorOfN(uint16L, entry)).hlist
|
|
|
|
).as[Cartridge]
|
|
|
|
|
|
|
|
lazy val boundary: Codec[Boundary] =
|
|
|
|
(uint16L :: uint16L :: uint16L).as[Boundary]
|
|
|
|
|
|
|
|
lazy val position: Codec[Position] =
|
|
|
|
(uint16L :: uint16L :: uint16L).as[Position]
|
|
|
|
|
|
|
|
lazy val face: Codec[Vector[Int]] = fixedSizeBytes(8L * 8L * 8L, vector(uint8L))
|
|
|
|
lazy val faces: Codec[Faces] =
|
|
|
|
(face :: face :: face :: face :: face :: face).as[Faces]
|
|
|
|
|
|
|
|
lazy val obj: Codec[Obj] = uint16L.xmap(Obj(_), _.id)
|
|
|
|
|
|
|
|
lazy val world: Codec[World] = boundary.flatPrepend { b =>
|
|
|
|
vectorOfN(provide(b.sizeLR * b.sizeDU * b.sizeNF), obj).hlist
|
|
|
|
}.as[World]
|
|
|
|
|
|
|
|
lazy val wires: Codec[Vector[Wire]] = vectorOfN(uint16L, wire)
|
|
|
|
lazy val wire: Codec[Wire] =
|
|
|
|
(position :: position :: position :: position.hlist).as[Wire]
|
|
|
|
|
|
|
|
lazy val metadatas: Codec[Vector[Metadata]] = vectorOfN(uint16L, metadata)
|
|
|
|
lazy val metadata: Codec[Metadata] =
|
|
|
|
discriminated[Metadata].by(uint16L)
|
|
|
|
.subcaseP(0x0100) {
|
2020-07-02 18:08:37 +00:00
|
|
|
case bool: Metadata.Bool => bool
|
|
|
|
} (metadataBool)
|
2020-07-02 17:26:19 +00:00
|
|
|
.subcaseP(0x0201) {
|
|
|
|
case pss: Metadata.PlaySoundSample => pss
|
|
|
|
} (metadataPlaySoundSample)
|
|
|
|
.subcaseP(0x0400) {
|
|
|
|
case num: Metadata.Number => num
|
|
|
|
} (metadataNumber)
|
|
|
|
.subcaseP(0x0500) {
|
|
|
|
case triple: Metadata.Triple => triple
|
|
|
|
} (metadataTriple)
|
|
|
|
.subcaseP(0x0600) {
|
|
|
|
case text: Metadata.Text => text
|
|
|
|
} (metadataText)
|
|
|
|
.subcaseP(0x0700) {
|
|
|
|
case terminal: Metadata.Terminal => terminal
|
|
|
|
} (metadataTerminal)
|
|
|
|
|
2020-07-02 18:08:37 +00:00
|
|
|
lazy val metadataBool: Codec[Metadata.Bool] =
|
|
|
|
(position :: bool(8).hlist).as[Metadata.Bool]
|
2020-07-02 17:26:19 +00:00
|
|
|
lazy val metadataPlaySoundSample: Codec[Metadata.PlaySoundSample] =
|
|
|
|
(position :: sample.hlist).as[Metadata.PlaySoundSample]
|
|
|
|
lazy val metadataNumber: Codec[Metadata.Number] =
|
|
|
|
(position :: floatL.hlist).as[Metadata.Number]
|
|
|
|
lazy val metadataTriple: Codec[Metadata.Triple] =
|
|
|
|
(position :: floatL :: floatL :: floatL.hlist).as[Metadata.Triple]
|
|
|
|
lazy val metadataText: Codec[Metadata.Text] =
|
|
|
|
(position :: fancadeString.hlist).as[Metadata.Text]
|
|
|
|
lazy val metadataTerminal: Codec[Metadata.Terminal] =
|
|
|
|
(position :: fancadeString.hlist).as[Metadata.Terminal]
|
|
|
|
|
|
|
|
lazy val sample: Codec[Metadata.Sample] =
|
|
|
|
discriminated[Metadata.Sample].by(uint16L)
|
|
|
|
.subcaseP(0) {
|
|
|
|
case chirp @ Metadata.Sample.Chirp => chirp
|
|
|
|
} (provide(Metadata.Sample.Chirp))
|
|
|
|
.subcaseP(1) {
|
|
|
|
case scrape @ Metadata.Sample.Scrape => scrape
|
|
|
|
} (provide(Metadata.Sample.Scrape))
|
|
|
|
.subcaseP(2) {
|
|
|
|
case squeek @ Metadata.Sample.Squeek => squeek
|
|
|
|
} (provide(Metadata.Sample.Squeek))
|
|
|
|
.subcaseP(3) {
|
|
|
|
case engine @ Metadata.Sample.Engine => engine
|
|
|
|
} (provide(Metadata.Sample.Engine))
|
|
|
|
.subcaseP(4) {
|
|
|
|
case button @ Metadata.Sample.Button => button
|
|
|
|
} (provide(Metadata.Sample.Button))
|
|
|
|
.subcaseP(5) {
|
|
|
|
case ball @ Metadata.Sample.Ball => ball
|
|
|
|
} (provide(Metadata.Sample.Ball))
|
|
|
|
.subcaseP(6) {
|
|
|
|
case piano @ Metadata.Sample.Piano => piano
|
|
|
|
} (provide(Metadata.Sample.Piano))
|
|
|
|
.subcaseP(7) {
|
|
|
|
case marimba @ Metadata.Sample.Marimba => marimba
|
|
|
|
} (provide(Metadata.Sample.Marimba))
|
|
|
|
.subcaseP(8) {
|
|
|
|
case pad @ Metadata.Sample.Pad => pad
|
|
|
|
} (provide(Metadata.Sample.Pad))
|
|
|
|
.subcaseP(9) {
|
|
|
|
case beep @ Metadata.Sample.Beep => beep
|
|
|
|
} (provide(Metadata.Sample.Beep))
|
|
|
|
.subcaseP(10) {
|
|
|
|
case plop @ Metadata.Sample.Plop => plop
|
|
|
|
} (provide(Metadata.Sample.Plop))
|
|
|
|
.subcaseP(11) {
|
|
|
|
case flop @ Metadata.Sample.Flop => flop
|
|
|
|
} (provide(Metadata.Sample.Flop))
|
|
|
|
.subcaseP(12) {
|
|
|
|
case splash @ Metadata.Sample.Splash => splash
|
|
|
|
} (provide(Metadata.Sample.Splash))
|
|
|
|
.subcaseP(13) {
|
|
|
|
case boom @ Metadata.Sample.Boom => boom
|
|
|
|
} (provide(Metadata.Sample.Boom))
|
|
|
|
.subcaseP(14) {
|
|
|
|
case hit @ Metadata.Sample.Hit => hit
|
|
|
|
} (provide(Metadata.Sample.Hit))
|
|
|
|
.subcaseP(15) {
|
|
|
|
case clang @ Metadata.Sample.Clang => clang
|
|
|
|
} (provide(Metadata.Sample.Clang))
|
|
|
|
.subcaseP(16) {
|
|
|
|
case jump @ Metadata.Sample.Jump => jump
|
|
|
|
} (provide(Metadata.Sample.Jump))
|
|
|
|
|
|
|
|
lazy val entry: Codec[Entry] =
|
|
|
|
( low ~ low ~ low ~ low ~
|
|
|
|
bool ~ bool ~ bool ~ bool ~
|
|
|
|
low ~ low ~ low ~ bool ~
|
|
|
|
high ~ low ~ low ~ low).consume {
|
|
|
|
case (_ ~ _ ~ _ ~ _ ~ isFaces ~ isWorld ~ isMetadata ~ isWires ~ _ ~ _ ~ _ ~ isVisible ~ _ ~ _ ~ _ ~ _) =>
|
|
|
|
(
|
|
|
|
optionC(isVisible, uint8L) ::
|
|
|
|
fancadeString ::
|
|
|
|
optionC(isFaces, faces) ::
|
|
|
|
optionC(isWorld, world) ::
|
|
|
|
optionC(isMetadata, metadatas) ::
|
|
|
|
optionC(isWires, wires).hlist
|
|
|
|
).as[Entry]
|
|
|
|
} {
|
|
|
|
case Entry(vFlags, _, f, wd, mt, wr) =>
|
|
|
|
(() ~ () ~ () ~ () ~ f.isDefined ~ wd.isDefined ~ mt.isDefined ~ wr.isDefined ~ () ~ () ~ () ~ vFlags.isDefined ~ () ~ () ~ () ~ ())
|
|
|
|
}
|
|
|
|
|
|
|
|
lazy val encCartridge: Codec[Cartridge] = zlib(cartridge)
|
|
|
|
|
|
|
|
}
|