1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
|
enum instruction_mode {
instruction_mode_scalar,
#if ARM
instruction_mode_neon,
#else
instruction_mode_sse,
instruction_mode_avx
#endif
};
static char* BlendmodeNames[] = {
"Normal",
"Multiply",
"Color Burn",
"Linear Burn",
"Add",
"Screen",
"Overlay",
"Soft Light",
"Hard Light",
"Subtract",
"Divide",
"Difference"
};
enum blend_mode
{
blend_normal,
blend_multiply,
blend_colorburn,
blend_linearburn,
blend_add,
blend_screen,
blend_overlay,
blend_softlight,
blend_hardlight,
blend_subtract,
blend_divide,
blend_difference
};
#define STRING_SIZE (1024 - sizeof(uint8)) // TODO(fox): Paths above STRING_SIZE length aren't handled properly.
struct block_string {
uint8 Occupied;
char Char[STRING_SIZE];
};
struct bitmap_cache_status
{
uint32 Block_End;
};
enum cache_entry_type
{
cache_entry_type_assert,
cache_entry_type_comp,
cache_entry_type_source
};
struct cache_entry
{
uint8 IsOccupied;
uint8 IsCached;
uint64 CycleTime;
uint32 Block_StartIndex;
enum cache_entry_type Type;
uint32 TypeInfo;
uint32 TypeInfo_Sub;
};
enum interpolation_type
{
interpolation_type_linear,
interpolation_type_bezier,
interpolation_type_hold
};
struct bezier_point {
uint8 Occupied;
v2 Pos[3];
interpolation_type Type;
bool32 IsSelected;
uint8 PointSelect[3];
uint8 Color;
};
struct block_bezier {
uint8 Occupied;
bezier_point Point[MAX_KEYFRAMES_PER_BLOCK];
};
enum selection_type
{
selection_type_none,
selection_type_layer,
selection_type_keyframe
};
struct clipboard_channel {
void *Name;
uint16 LayerOffset;
uint16 KeyframeCount;
};
struct clipboard_contents {
selection_type Type;
clipboard_channel Channel[16];
uint16 ChannelCount;
};
struct layer_bitmap_state {
// Image and video
bool32 ToUpdate = 1;
// GL state
// gl_effect_layer Test;
// gl_effect_layer TestM;
// Video state
int32 CurrentFrame = -1; // The last frame number rendered to the bitmap. -1 gurantees a load upon layer creation.
void *AVInfo; // Internal data containing current frame info
};
struct render_state
{
struct layer_bitmap_state Bitmap[MAX_LAYERS];
cache_entry Entry[2048];
};
struct render_queue_item
{
bool32 Type;
v2 Pos;
};
struct render_queue
{
uint16 Playhead;
uint16 CurrentIdx;
render_queue_item Item[512];
};
enum focused_window
{
focus_viewport,
focus_properties,
focus_timeline
};
struct sorted_property_array
{
uint32 MinYIndex;
uint32 MaxYIndex;
};
struct sorted_comp_array
{
uint32 LayerCount;
uint32 CurrentSortIndex; // Used intermediately in the sorting algorithm
real32 DisplaySize;
};
struct sorted_layer_array
{
uint16 Block_Layer_Index;
real32 SortedOffset;
real32 DisplayOffset;
uint16 Sorted_Effect_Index[MAX_EFFECTS];
uint16 SortedPropertyStart;
uint16 SortedKeyframeStart;
};
struct sorted_file
{
sorted_comp_array *CompArray;
sorted_layer_array *LayerArray;
sorted_property_array *PropertyStart;
uint16 *PropertyArray;
uint16 *SourceArray; // sorted by 'recency,' wip for stablediffusion stuff
uint16 TempSourceCount;
uint64 Layer_SortSize;
uint64 Property_SortSize;
uint64 Source_SortSize;
};
enum timeline_mode
{
timeline_mode_default,
timeline_mode_graph
};
struct pen_state {
bool32 IsActive;
};
struct brush_state
{
ImVec2 UIPos; // Initial position when ctrl is held
real32 Size = 256; // Maxes at 1024 for now
real32 Hardness = 0.55f; // From 1 to 100
real32 Spacing = 1.0f;
bool32 EraseMode = 0;
GLuint GLTexture;
v2 PrevPos;
void *PaintBuffer;
void *TransientBitmap;
uint32 LayerToPaint_Index = -1;
rectangle CacheBounds = { 99999, 99999, -99999, -99999 };
};
enum interact_type
{
interact_type_none,
interact_type_timeline_scrub,
interact_type_slider_scrub,
interact_type_layer_move,
interact_type_layer_timeadjust,
interact_type_viewport_transform,
interact_type_keyframe_move,
interact_type_keyframe_scale,
interact_type_keyframe_rotate,
interact_type_brush
};
char *ToolName[] {
"Move",
"Crop",
"Brush",
"Pen"
};
enum tool {
tool_default,
tool_crop,
tool_brush,
tool_pen,
tool_count
};
struct interact_transform
{
v2 Min;
v2 Max;
real32 Radians;
v2 Position;
real32 Scale = 1.0f;
ImVec2 OGPos;
uint32 TransformMode;
};
enum hotkey_input
{
hotkey_none,
hotkey_newpaintlayer,
hotkey_newlayerfromsource,
hotkey_deletelayer,
hotkey_undo,
hotkey_redo,
};
enum property_display_type
{
property_display_type_standard,
property_display_type_blendmode,
property_display_type_color
};
struct header_property
{
char *Name;
real32 DefaultValue;
property_display_type DisplayType;
real32 MinVal;
real32 MaxVal;
bool32 AlwaysInteger;
};
struct gl_effect_layer {
bool32 Initialized;
GLuint Texture;
GLuint FramebufferObject;
uint32 Color_Renderbuffer;
uint32 Stencil_Renderbuffer;
};
enum effect_display_type
{
effect_display_type_standard,
effect_display_type_levels,
effect_display_type_curves
};
struct block_effect
{
uint8 Occupied;
char ID[8];
bool32 IsToggled;
uint32 Block_Property_Index[MAX_PROPERTIES_PER_EFFECT];
real32 ExtraData[16];
};
struct header_effect
{
char *Name;
char *ID; // Eight-letter string that's used in the actual file
void (*func)(real32 *, int, int, int, void *, uint16);
uint16 PropertyStartIndex;
uint16 Property_Count;
effect_display_type DisplayType;
bool32 UseGL;
uint32 GLShaderIndex;
};
enum imgui_popups
{
popup_none,
popup_saveas,
popup_keybinds
};
struct project_state
{
bool32 UpdateKeyframes = 0;
bool32 UpdateFrame = 1; // only refreshes frame; set UpdateKeyframes to update animation
bool32 DebugDisableCache = 1;
// bad
uint32 CachedFrameCount;
int32 LastCachedFrame = -10000;
uint64 HotFramePerf = 0;
uint32 AVCount;
render_state Render;
render_queue Queue;
int32 Frame_Current;
tool Tool = tool_default;
// GLuint ToolIconTex[(int)tool_count];
pen_state Pen = {};
brush_state Brush;
#if STABLE
int32 CurlActive = 0;
char JSONPayload[1024*1024*4];
real32 SDPercentDone;
real32 SDTimeEstimate;
real64 SDTimer;
#endif
header_effect Effect[128];
header_property Property[512];
uint16 Playhead_Effect;
uint16 Playhead_Property;
int32 PreviewLayer = -1;
int32 PreviewSource = -1;
hotkey_input HotkeyInput;
void *Dump1;
void *Dump2;
char DummyName[512];
char DummyName2[512];
bool32 IsRunning = 1;
bool32 IsPlaying;
bool32 PlayAudio;
int32 FramePlayingCount;
bool32 FirstFrame = 1;
int32 AudioLayerIndex = -1;
void *ClipboardBuffer;
uint64 ClipboardSize;
int16 MostRecentlySelectedLayer = -1;
// NOTE(fox): Try to use this only where you actually need it (the
// ambiguous case of copying keyframes versus layers), since this state
// transfer will get buggy if you expand it to everything.
selection_type RecentSelectionType = selection_type_none;
interact_type Interact_Active;
int32 Interact_Modifier;
real32 Interact_Offset[12];
void *Interact_Address;
// NOTE(fox): We need to keep track of when the user changes the CurrentValue of a
// channel that has keyframes on it (i.e. CurrentValue will now evaluate to
// its previous value unless the user adds a new keyframe to the channel)
// so we can purge the cache if the user changes to a different frame.
int UncommitedKeyframe;
int32 Initializing = 3;
int32 MsgTime; // currently in "frames"
char *Msg;
imgui_popups ImGuiPopups;
char Filename[512];
ImGuiTextFilter filter; // This filter API is pretty ballin'.
bool32 RerouteEffects; // Allows shift+space hotkey to gain focus on the effects panel.
ImDrawListSplitter Test;
ImDrawListSplitter Split_KeybindUI;
int32 Warp_X = 0;
int32 Warp_Y = 0;
bool32 Warp_WantSetPos = false;
ImVec2 Warp_PositionToSet;
real32 Warp_PositionInitial;
int32 Warp_Direction;
uint32 InteractTransformMode; // Whether a drag on the Shift+T UI is scale (1), rotation (2), or position (3).
timeline_mode TimelineMode;
bool32 BoxSelect;
focused_window FocusedWindow; // Convenience for adding window-specific hotkeys.
bool32 SetFocus;
v2 TempZoomRatio = V2(1, 1);
};
// UI info that's saved to the file and is not part of the history tree
struct ui
{
ImVec2 CompZoom; // In screen pixels, not percentage.
ImVec2 CompPos;
// Under 1 is zoomed in!
ImVec2 TimelinePercentZoomed;
ImVec2 TimelinePercentOffset;
ImVec2 GraphZoomSize;
ImVec2 GraphMoveSize;
v4 Color = {1, 1, 1, 1};
v4 AltColor = {0, 0, 0, 1};
bool32 IsPrimary;
#if STABLE
sd_state SD;
bool32 StableEnabled = 0;
#endif
ImU32 LayerColors[16] = {
0xff8b1f1f,
0xffc25909,
0xff57c20a,
0xff8ee6da,
0xffa48fb7,
0xffd14061,
0xff38b683,
0xff3fdbe5,
0xffc9c9c9,
0xff978489,
0xfffaf5ab,
0xff101010,
0xffa024ca,
0xfffae920,
0xff208dfa,
0xfffa2051
};
};
struct project_data
{
uint8 Occupied;
uint16 Layer_Count;
uint16 Source_Count;
uint16 Comp_Count;
uint16 PrincipalCompIndex;
ui UI;
};
struct block_composition
{
uint8 Occupied;
uint16 Name_String_Index;
uint16 Width;
uint16 Height;
uint16 BytesPerPixel;
uint16 FPS;
uint32 Frame_Count;
int32 Frame_Start;
int32 Frame_End;
};
struct layer_transforms
{
real32 x;
real32 y;
real32 ax;
real32 ay;
real32 rotation;
real32 scale;
};
enum source_type {
source_type_none,
source_type_principal,
source_type_principal_temp,
source_type_file
};
struct block_source
{
uint8 Occupied;
bool32 IsSelected;
uint16 Path_String_Index;
uint16 Name_String_Index;
// Only used for type_principal
uint16 Bitmap_Index;
uint16 Width;
uint16 Height;
uint16 BytesPerPixel;
// LibAV specific
real32 FPS;
bool32 HasAudio;
bool32 HasVideo;
uint32 RelativeTimestamp;
GLuint ThumbnailTex;
source_type Type;
};
struct property_channel {
uint8 Occupied;
uint16 Block_Bezier_Index[MAX_KEYFRAME_BLOCKS];
uint16 Block_Bezier_Count;
uint16 Keyframe_Count;
int32 Identifier;
real32 CurrentValue;
real32 MaxVal;
real32 MinVal;
bool32 AlwaysInteger;
real32 ScrubVal; // increment when dragging on sliders, etc.
bool32 IsToggled;
};
char *DefaultChannel[] = { "X Position", "Y Position", "Anchor X", "Anchor Y",
"Rotation", "Scale", "Opacity", "Frame Number" };
struct block_layer {
uint8 Occupied;
bool32 IsPrecomp;
bool32 Precomp_Toggled;
// NOTE(fox): References a precomp index if IsPrecomp is true, not a source index.
uint16 Block_Source_Index;
uint16 Block_String_Index;
// References the precomp that the layer belongs to.
uint16 Block_Composition_Index;
uint16 Block_Mask_Index[MAX_MASKS];
uint16 Block_Mask_Count;
uint16 Block_Effect_Index[MAX_EFFECTS];
uint16 Block_Effect_Count;
blend_mode BlendMode;
union
{
property_channel Property[8];
struct
{
property_channel x;
property_channel y;
property_channel ax;
property_channel ay;
property_channel rotation;
property_channel scale;
property_channel opacity;
property_channel time;
};
};
bool32 IsSelected;
bool32 IsVisible;
bool32 IsAdjustment;
// NOTE(fox): I use these in some places without calling
// Interact_Evaluate_Layer(), because I'm assuming it's impossible for
// layer dragging to happen in those contexts. Check for this if weird bugs appear.
int32 Frame_Start;
int32 Frame_End;
// This is what changes when the layer is dragged. It also marks the starting frame for video footage.
int32 Frame_Offset;
real32 Vertical_Offset;
real32 Vertical_Height = 1;
uint16 ColIndex;
};
struct render_byte_info {
uint32 MaskPixel;
uint32 ByteOffset;
uint32 Bits;
real32 Normalized;
};
struct transform_info {
real32 XAxisPX;
real32 XAxisPY;
real32 YAxisPX;
real32 YAxisPY;
real32 LayerWidth;
real32 LayerHeight;
real32 LayerBytesPerPixel;
real32 LayerPitch;
render_byte_info LayerBits;
real32 BufferWidth;
real32 BufferHeight;
real32 BufferBytesPerPixel;
real32 BufferPitch;
render_byte_info BufferBits;
real32 LayerOpacity;
real32 OriginX;
real32 OriginY;
blend_mode BlendMode;
bool32 IsAdjustment;
rectangle ClipRect;
void *SourceBuffer;
};
struct direct_info {
real32 BufferWidth;
real32 BufferHeight;
real32 BufferBytesPerPixel;
real32 BufferPitch;
render_byte_info BufferBits;
real32 Opacity;
blend_mode BlendMode;
rectangle ClipRect;
void *SourceBuffer;
bool32 SwapActive;
bool32 OnlyBlendAlpha;
};
struct brush_info {
uint32 BrushLength;
rectangle LayerBounds;
uint32 LayerPitch;
uint32 BrushPitch;
int32 ExtraX;
int32 ExtraY;
render_byte_info LayerBits;
render_byte_info BrushBits;
int BytesPerPixel;
int SourceWidth;
int SourceBytesPerPixel;
void *SourceBuffer;
void *BrushBuffer;
real32 R_Brush;
real32 G_Brush;
real32 B_Brush;
real32 A_Brush;
bool32 EraseMode;
uint8 *BrushRow;
};
enum render_type {
render_type_main,
render_type_notransform,
render_type_notransform_swap,
render_type_brush
};
struct render_entry {
void *RenderData;
void *OutputBuffer;
render_type RenderType;
rectangle RenderRegion;
};
|