// // File: foldhaus_animation_serializer.cpp // Author: Peter Slattery // Creation Date: 2020-10-04 // #ifndef FOLDHAUS_ANIMATION_SERIALIZER_CPP internal gs_string AnimSerializer_Serialize(animation Anim, animation_clip* GlobalClips, gs_memory_arena* Arena) { serializer Serializer = {0}; Serializer.String = PushString(Arena, 4096); Serializer.Identifiers = AnimationFieldStrings; Serializer.IdentifiersCount = AnimField_Count; Serializer_WriteF(&Serializer, "%S;\n", AnimationFieldStrings[AnimField_FileIdent]); Serializer_WriteStringValue(&Serializer, AnimField_AnimName, Anim.Name.ConstString); Serializer_WriteValue(&Serializer, AnimField_LayersCount, Anim.Layers.Count); Serializer_WriteValue(&Serializer, AnimField_BlocksCount, Anim.Blocks_.Count); Serializer_OpenStruct(&Serializer, AnimField_PlayableRange); { Serializer_WriteValue(&Serializer, AnimField_PlayableRangeMin, (u32)Anim.PlayableRange.Min); Serializer_WriteValue(&Serializer, AnimField_PlayableRangeMax, (u32)Anim.PlayableRange.Max); } Serializer_CloseStruct(&Serializer); Serializer_OpenStruct(&Serializer, AnimField_LayersArray); for (u32 i = 0; i < Anim.Layers.Count; i++) { anim_layer LayerAt = Anim.Layers.Values[i]; Serializer_OpenStruct(&Serializer, AnimField_Layer); { Serializer_WriteStringValue(&Serializer, AnimField_LayerName, LayerAt.Name.ConstString); Serializer_WriteStringValue(&Serializer, AnimField_LayerBlendMode, BlendModeStrings[LayerAt.BlendMode]); } Serializer_CloseStruct(&Serializer); } Serializer_CloseStruct(&Serializer); Serializer_OpenStruct(&Serializer, AnimField_BlocksArray); for (u32 i = 0; i < Anim.Blocks_.Count; i++) { // TODO(pjs): Handle free'd animation blocks animation_block AnimationBlockAt = Anim.Blocks_.Values[i]; // TODO(pjs): Systematize the AnimationProcHandle // :AnimProcHandle u32 AnimationProcIndex = AnimationBlockAt.AnimationProcHandle - 1; animation_clip Animation = GlobalClips[AnimationProcIndex]; Serializer_OpenStruct(&Serializer, AnimField_Block); { Serializer_OpenStruct(&Serializer, AnimField_BlockFrameRange); { Serializer_WriteValue(&Serializer, AnimField_BlockFrameRangeMin, (u32)AnimationBlockAt.Range.Min); Serializer_WriteValue(&Serializer, AnimField_BlockFrameRangeMax, (u32)AnimationBlockAt.Range.Max); } Serializer_CloseStruct(&Serializer); Serializer_WriteValue(&Serializer, AnimField_BlockLayerIndex, AnimationBlockAt.Layer); Serializer_WriteStringValue(&Serializer, AnimField_BlockAnimName, ConstString(Animation.Name)); } Serializer_CloseStruct(&Serializer); } Serializer_CloseStruct(&Serializer); return Serializer.String; } internal animation AnimParser_Parse(gs_string File, gs_memory_arena* Arena, u32 AnimClipsCount, animation_clip* AnimClips) { animation Result = {0}; parser Parser = {0}; Parser.String = File; Parser.At = Parser.String.Str; Parser.Identifiers = AnimationFieldStrings; Parser.IdentifiersCount = AnimField_Count; Parser.Arena = Arena; if (Parser_ReadString(&Parser, AnimationFieldStrings[AnimField_FileIdent])) { Result.Name = Parser_ReadStringValue(&Parser, AnimField_AnimName); Result.Layers.CountMax = Parser_ReadU32Value(&Parser, AnimField_LayersCount); Result.Layers.Values = PushArray(Arena, anim_layer, Result.Layers.CountMax); Result.Blocks_.CountMax = Parser_ReadU32Value(&Parser, AnimField_BlocksCount); Result.Blocks_.Generations = PushArray(Arena, u32, Result.Blocks_.CountMax); Result.Blocks_.Values = PushArray(Arena, animation_block, Result.Blocks_.CountMax); if (Parser_ReadOpenStruct(&Parser, AnimField_PlayableRange)) { Result.PlayableRange.Min = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMin); Result.PlayableRange.Max = Parser_ReadU32Value(&Parser, AnimField_PlayableRangeMax); if (Parser_ReadCloseStruct(&Parser)) { // TODO(pjs): Error } } else { // TODO(pjs): Error } if (Parser_ReadOpenStruct(&Parser, AnimField_LayersArray)) { while (!Parser_ReadCloseStruct(&Parser)) { anim_layer Layer = {0}; if (Parser_ReadOpenStruct(&Parser, AnimField_Layer)) { Layer.Name = Parser_ReadStringValue(&Parser, AnimField_LayerName); gs_string BlendModeName = Parser_ReadStringValue(&Parser, AnimField_LayerBlendMode); for (u32 i = 0; i < BlendMode_Count; i++) { if (StringsEqual(BlendModeName.ConstString, BlendModeStrings[i])) { Layer.BlendMode = (blend_mode)i; break; } } if (Parser_ReadCloseStruct(&Parser)) { Animation_AddLayer(&Result, Layer); } else { // TODO(pjs): Error } } } } if (Parser_ReadOpenStruct(&Parser, AnimField_BlocksArray)) { while(!Parser_ReadCloseStruct(&Parser)) { animation_block Block = {0}; if (Parser_ReadOpenStruct(&Parser, AnimField_Block)) { if (Parser_ReadOpenStruct(&Parser, AnimField_BlockFrameRange)) { Block.Range.Min = Parser_ReadU32Value(&Parser, AnimField_BlockFrameRangeMin); Block.Range.Max = Parser_ReadU32Value(&Parser, AnimField_BlockFrameRangeMax); Parser_ReadCloseStruct(&Parser); } else { // TODO(pjs): Error } Block.Layer = Parser_ReadU32Value(&Parser, AnimField_BlockLayerIndex); // TODO(pjs): AnimName -> Animation Proc Handle gs_string AnimName = Parser_ReadStringValue(&Parser, AnimField_BlockAnimName); Block.AnimationProcHandle = 0; for (u32 i = 0; i < AnimClipsCount; i++) { if (StringEqualsCharArray(AnimName.ConstString, AnimClips[i].Name, CStringLength(AnimClips[i].Name))) { Block.AnimationProcHandle = i + 1; break; } } if (Parser_ReadCloseStruct(&Parser)) { AnimBlockArray_Push(&Result.Blocks_, Block); } else { // TODO(pjs): Error } } } } } return Result; } #define FOLDHAUS_ANIMATION_SERIALIZER_CPP #endif // FOLDHAUS_ANIMATION_SERIALIZER_CPP