lots of little fixes
This commit is contained in:
parent
741529a664
commit
59cac0f435
|
@ -175,7 +175,7 @@ ConstructAssemblyFromDefinition (assembly_definition Definition,
|
|||
r32 PercentStep = 1 / (r32)LEDsInStripCount;
|
||||
for (s32 Step = 0; Step < LEDsInStripCount; Step++)
|
||||
{
|
||||
v3 LEDPosition = Lerp(WS_StripStart, WS_StripEnd, Percent);
|
||||
v4 LEDPosition = V4(Lerp(WS_StripStart, WS_StripEnd, Percent), 1);
|
||||
s32 LEDIndex = LEDBuffer->Count++;
|
||||
Assert(LEDIndex < LEDCount);
|
||||
|
||||
|
@ -183,7 +183,6 @@ ConstructAssemblyFromDefinition (assembly_definition Definition,
|
|||
sacn_pixel* LEDColor = LEDBuffer->Colors + LEDIndex;
|
||||
|
||||
LED->Position = LEDPosition;
|
||||
LED->PositionMatrix = GetPositionM44(V4(LED->Position, 1));
|
||||
LED->Index = LEDIndex;
|
||||
|
||||
Percent += PercentStep;
|
||||
|
@ -242,13 +241,14 @@ DrawLEDsInBufferRangeJob (s32 ThreadID, void* JobData)
|
|||
sacn_pixel SACNColor = Data->Colors[LED->Index];
|
||||
v4 Color = v4{SACNColor.R / 255.f, SACNColor.G / 255.f, SACNColor.B / 255.f, 1.0f};
|
||||
|
||||
m44 ModelMatrix = Data->FaceCameraMatrix * LED->PositionMatrix;// * Data->FaceCameraMatrix;
|
||||
|
||||
v4 P0 = ModelMatrix * P0_In;
|
||||
v4 P1 = ModelMatrix * P1_In;
|
||||
v4 P2 = ModelMatrix * P2_In;
|
||||
v4 P3 = ModelMatrix * P3_In;
|
||||
v4 V4Position = LED->Position;
|
||||
V4Position.w = 0;
|
||||
v4 P0 = P0_In + V4Position;
|
||||
v4 P1 = P1_In + V4Position;
|
||||
v4 P2 = P2_In + V4Position;
|
||||
v4 P3 = P3_In + V4Position;
|
||||
|
||||
DEBUG_TRACK_SCOPE(PushLEDTris);
|
||||
PushTri3DOnBatch(Data->Batch, P0, P1, P2, UV0, UV1, UV2, Color, Color, Color);
|
||||
PushTri3DOnBatch(Data->Batch, P0, P2, P3, UV0, UV2, UV3, Color, Color, Color);
|
||||
|
||||
|
@ -457,7 +457,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
|||
|
||||
GlobalDebugServices->Interface.RenderSculpture = true;
|
||||
|
||||
State->NodeList = AllocateNodeList(State->Permanent, Kilobytes(64));
|
||||
State->NodeList = AllocateNodeList(State->Permanent, 512); //Kilobytes(64));
|
||||
State->OutputNode = PushOutputNodeOnList(State->NodeList, v2{500, 250}, State->Permanent);
|
||||
{
|
||||
State->NodeRenderSettings.PortColors[MemberType_r32] = RedV4;
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
struct led
|
||||
{
|
||||
s32 Index;
|
||||
v3 Position;
|
||||
m44 PositionMatrix;
|
||||
v4 Position;
|
||||
};
|
||||
|
||||
struct led_buffer
|
||||
|
@ -63,19 +62,18 @@ struct app_state
|
|||
memory_arena* Transient;
|
||||
memory_arena SACNMemory;
|
||||
|
||||
camera Camera;
|
||||
|
||||
operation_mode_system Modes;
|
||||
|
||||
input_command_registry DefaultInputCommandRegistry;
|
||||
|
||||
input_command_queue CommandQueue;
|
||||
text_entry ActiveTextEntry;
|
||||
|
||||
streaming_acn SACN;
|
||||
s32 TotalLEDsCount;
|
||||
led_buffer* LEDBufferList;
|
||||
|
||||
camera Camera;
|
||||
r32 PixelsToWorldScale;
|
||||
|
||||
operation_mode_system Modes;
|
||||
input_command_registry DefaultInputCommandRegistry;
|
||||
input_command_queue CommandQueue;
|
||||
text_entry ActiveTextEntry;
|
||||
|
||||
// TODO(Peter): Make this dynamic. We want them contiguous in memory since we'll be accessing them
|
||||
// mostly by looping through them. On the other hand, I don't expect there to ever be more than 100
|
||||
// of them at once.
|
||||
|
@ -83,23 +81,19 @@ struct app_state
|
|||
assembly AssemblyList[ASSEMBLY_LIST_LENGTH];
|
||||
s32 AssembliesUsed;
|
||||
|
||||
bitmap_font* Font;
|
||||
interface_config Interface;
|
||||
|
||||
r32 PixelsToWorldScale;
|
||||
|
||||
node_list* NodeList;
|
||||
interface_node* OutputNode;
|
||||
|
||||
node_render_settings NodeRenderSettings;
|
||||
|
||||
bitmap_font* Font;
|
||||
interface_config Interface;
|
||||
};
|
||||
|
||||
internal void OpenColorPicker(app_state* State, v4* Address);
|
||||
|
||||
#include "foldhaus_node.cpp"
|
||||
#include "foldhaus_debug_visuals.h"
|
||||
#include "foldhaus_sacn_view.cpp"
|
||||
#include "foldhaus_node.cpp"
|
||||
#include "foldhaus_text_entry.cpp"
|
||||
#include "foldhaus_search_lister.cpp"
|
||||
|
||||
|
|
|
@ -109,6 +109,13 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
|||
DrawString(RenderBuffer, DebugString, Interface.Font,
|
||||
TopOfScreenLinePos, WhiteV4);
|
||||
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
||||
|
||||
PrintF(&DebugString, "Nodes Memory: %d / %d",
|
||||
State->NodeList->TotalUsed,
|
||||
State->NodeList->TotalMax);
|
||||
DrawString(RenderBuffer, DebugString, Interface.Font,
|
||||
TopOfScreenLinePos, WhiteV4);
|
||||
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
||||
}
|
||||
|
||||
if (GlobalDebugServices->Interface.ShowTrackedScopes)
|
||||
|
|
|
@ -585,7 +585,8 @@ FOLDHAUS_INPUT_COMMAND_PROC(NodeViewDeleteNode)
|
|||
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
||||
if (OpState->SelectedNodeHandle > 0)
|
||||
{
|
||||
|
||||
interface_node* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle);
|
||||
FreeNodeOnList(State->NodeList, SelectedNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,19 +595,12 @@ FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeView)
|
|||
DeactivateCurrentOperationMode(&State->Modes);
|
||||
}
|
||||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(DEBUGGetNode)
|
||||
{
|
||||
interface_node* Node = GetNodeWithHandle(State->NodeList, 3);
|
||||
s32 x = 5;
|
||||
}
|
||||
|
||||
input_command NodeViewCommands [] = {
|
||||
{ KeyCode_Tab, KeyCode_Invalid, Command_Began, CloseNodeView},
|
||||
{ KeyCode_A, KeyCode_Invalid, Command_Began, OpenNodeLister},
|
||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, NodeViewBeginMouseDragInteraction},
|
||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, NodeViewBeginMouseSelectInteraction},
|
||||
{ KeyCode_X, KeyCode_Invalid, Command_Began, NodeViewDeleteNode},
|
||||
{ KeyCode_B, KeyCode_Invalid, Command_Began, DEBUGGetNode},
|
||||
};
|
||||
|
||||
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView)
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
inline s32
|
||||
GetNodeMemorySize(s32 ConnectionsCount, s32 NameLength)
|
||||
{
|
||||
s32 Result = sizeof(interface_node) + (sizeof(node_connection) * ConnectionsCount) + sizeof(NameLength);
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline s32
|
||||
GetNodeMemorySize (interface_node Node)
|
||||
{
|
||||
s32 Result = sizeof(interface_node) + (sizeof(node_connection) * Node.ConnectionsCount) + sizeof(Node.Name);
|
||||
return Result;
|
||||
return GetNodeMemorySize(Node.ConnectionsCount, Node.Name.Length);
|
||||
}
|
||||
|
||||
internal node_list_iterator
|
||||
|
@ -10,7 +16,9 @@ GetNodeListIterator(node_list List)
|
|||
{
|
||||
node_list_iterator Result = {};
|
||||
Result.List = List;
|
||||
Result.At = (interface_node*)List.Memory;
|
||||
Result.CurrentBuffer = List.First;
|
||||
Result.At = (interface_node*)Result.CurrentBuffer->Memory;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
@ -18,37 +26,59 @@ internal b32
|
|||
NodeIteratorIsValid(node_list_iterator Iter)
|
||||
{
|
||||
b32 Result = (Iter.At != 0);
|
||||
Result &= (((u8*)Iter.At - Iter.List.Memory) < Iter.List.Used);
|
||||
Result &= (((u8*)Iter.At - Iter.CurrentBuffer->Memory) < Iter.CurrentBuffer->Used);
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
Next (node_list_iterator* Iter)
|
||||
{
|
||||
s32 SkipAmount = GetNodeMemorySize(*Iter->At);
|
||||
if (((u8*)Iter->At - Iter->List.Memory) + SkipAmount < Iter->List.Used)
|
||||
if (Iter->At->Handle == 0)
|
||||
{
|
||||
node_free_list_member* FreeNode = (node_free_list_member*)Iter->At;
|
||||
s32 SkipAmount = FreeNode->Size;
|
||||
Iter->At = (interface_node*)((u8*)Iter->At + SkipAmount);
|
||||
}
|
||||
else if (Iter->List.Next)
|
||||
{
|
||||
Iter->List = *Iter->List.Next;
|
||||
Iter->At = (interface_node*)Iter->List.Memory;
|
||||
}
|
||||
else
|
||||
{
|
||||
Iter->At = 0;
|
||||
s32 SkipAmount = GetNodeMemorySize(*Iter->At);
|
||||
if (((u8*)Iter->At - Iter->CurrentBuffer->Memory) + SkipAmount < Iter->CurrentBuffer->Used)
|
||||
{
|
||||
Iter->At = (interface_node*)((u8*)Iter->At + SkipAmount);
|
||||
if (Iter->At->Handle == 0) { Next(Iter); }
|
||||
}
|
||||
else if (Iter->CurrentBuffer->Next)
|
||||
{
|
||||
Iter->CurrentBuffer = Iter->CurrentBuffer->Next;
|
||||
Iter->At = (interface_node*)Iter->CurrentBuffer->Memory;
|
||||
if (Iter->At->Handle == 0) { Next(Iter); }
|
||||
}
|
||||
else
|
||||
{
|
||||
Iter->At = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal node_list*
|
||||
AllocateNodeList (memory_arena* Storage, s32 Size)
|
||||
internal node_list_buffer*
|
||||
AllocateNodeListBuffer (memory_arena* Storage, s32 Size)
|
||||
{
|
||||
node_list* Result = PushStruct(Storage, node_list);
|
||||
node_list_buffer* Result = PushStruct(Storage, node_list_buffer);;
|
||||
Result->Memory = PushSize(Storage, Size);
|
||||
Result->Max = Size;
|
||||
Result->Used = 0;
|
||||
Result->Next = 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal node_list*
|
||||
AllocateNodeList (memory_arena* Storage, s32 InitialSize)
|
||||
{
|
||||
node_list* Result = PushStruct(Storage, node_list);
|
||||
Result->First = AllocateNodeListBuffer(Storage, InitialSize);
|
||||
Result->Head = Result->First;
|
||||
Result->TotalMax = InitialSize;
|
||||
Result->TotalUsed = 0;
|
||||
Result->HandleAccumulator = 0;
|
||||
return Result;
|
||||
}
|
||||
|
@ -58,32 +88,39 @@ PushNodeOnList (node_list* List, s32 NameLength, s32 ConnectionsCount, v2 Min, v
|
|||
{
|
||||
interface_node* Result = 0;
|
||||
|
||||
if (List->Used >= List->Max)
|
||||
s32 NodeMemorySize = GetNodeMemorySize(ConnectionsCount, NameLength);
|
||||
|
||||
if (List->TotalUsed + NodeMemorySize >= List->TotalMax)
|
||||
{
|
||||
if (!List->Next)
|
||||
{
|
||||
List->Next = AllocateNodeList(Storage, List->Max);
|
||||
}
|
||||
Result = PushNodeOnList(List->Next, NameLength, ConnectionsCount, Min, Dim, Storage);
|
||||
node_list_buffer* Buf = AllocateNodeListBuffer(Storage, List->Head->Max);
|
||||
List->Head->Next = Buf;
|
||||
List->Head = Buf;
|
||||
List->TotalMax += Buf->Max;
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = (interface_node*)(List->Memory + List->Used);
|
||||
Result->Handle = ++List->HandleAccumulator;
|
||||
Result->Name = MakeString((char*)(Result + 1), NameLength);
|
||||
Assert(List->TotalUsed + NodeMemorySize <= List->TotalMax);
|
||||
|
||||
Result->ConnectionsCount = ConnectionsCount;
|
||||
Result->Connections = (node_connection*)(Result->Name.Memory + NameLength);
|
||||
Result = (interface_node*)(List->Head->Memory + List->Head->Used);
|
||||
Result->Handle = ++List->HandleAccumulator;
|
||||
Result->Name = MakeString((char*)(Result + 1), NameLength);
|
||||
|
||||
Result->Min = Min;
|
||||
Result->Dim = Dim;
|
||||
Result->ConnectionsCount = ConnectionsCount;
|
||||
Result->Connections = (node_connection*)(Result->Name.Memory + NameLength);
|
||||
|
||||
List->Used += GetNodeMemorySize(*Result);
|
||||
}
|
||||
Result->Min = Min;
|
||||
Result->Dim = Dim;
|
||||
|
||||
List->Head->Used += NodeMemorySize;
|
||||
List->TotalUsed += NodeMemorySize;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
FreeNodeOnList (node_list* List, interface_node* Node)
|
||||
{
|
||||
// TODO(Peter):
|
||||
}
|
||||
|
||||
internal void
|
||||
InitializeNodeConnection (node_connection* Connection, struct_member_type Type, b32 DirectionMask)
|
||||
{
|
||||
|
@ -174,16 +211,15 @@ GetNodeWithHandle(node_list* List, s32 Handle)
|
|||
DEBUG_TRACK_FUNCTION;
|
||||
interface_node* Result = 0;
|
||||
|
||||
u8* At = List->Memory;
|
||||
while(At - List->Memory < List->Used)
|
||||
node_list_iterator Iter = GetNodeListIterator(*List);
|
||||
while (NodeIteratorIsValid(Iter))
|
||||
{
|
||||
interface_node* Node = (interface_node*)At;
|
||||
if(Node->Handle == Handle)
|
||||
if(Iter.At->Handle == Handle)
|
||||
{
|
||||
Result = Node;
|
||||
Result = Iter.At;
|
||||
break;
|
||||
}
|
||||
At += GetNodeMemorySize(*Node);
|
||||
Next(&Iter);
|
||||
}
|
||||
|
||||
return Result;
|
||||
|
|
|
@ -74,7 +74,7 @@ struct node_connection
|
|||
#define NODE_CONNECTIONS_MAX 8
|
||||
struct interface_node
|
||||
{
|
||||
s32 Handle;
|
||||
s32 Handle; // NOTE(Peter): stores a non-zero handle. must come first to match node_free_list_member
|
||||
string Name;
|
||||
|
||||
v2 Min, Dim;
|
||||
|
@ -88,13 +88,29 @@ struct interface_node
|
|||
u8* PersistentData;
|
||||
};
|
||||
|
||||
struct node_list
|
||||
struct node_free_list_member
|
||||
{
|
||||
s32 Handle; // NOTE(Peter): this will always be zero, and must come first to match interface_node
|
||||
s32 Size;
|
||||
node_free_list_member* Next;
|
||||
s32 OldHandle;
|
||||
};
|
||||
|
||||
struct node_list_buffer
|
||||
{
|
||||
u8* Memory;
|
||||
s32 Max;
|
||||
s32 Used;
|
||||
|
||||
node_list* Next;
|
||||
node_list_buffer* Next;
|
||||
};
|
||||
|
||||
struct node_list
|
||||
{
|
||||
node_list_buffer* First;
|
||||
node_list_buffer* Head;
|
||||
s32 TotalMax;
|
||||
s32 TotalUsed;
|
||||
|
||||
s32 HandleAccumulator;
|
||||
};
|
||||
|
@ -102,6 +118,7 @@ struct node_list
|
|||
struct node_list_iterator
|
||||
{
|
||||
node_list List;
|
||||
node_list_buffer* CurrentBuffer;
|
||||
interface_node* At;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ FilterSearchLister (search_lister* SearchLister)
|
|||
}
|
||||
}
|
||||
|
||||
SearchLister->HotItem = GSClamp(0, SearchLister->HotItem, SearchLister->FilteredListCount - 1);
|
||||
|
||||
if (SearchLister->FilteredListCount == 0)
|
||||
{
|
||||
SearchLister->HotItem = -1;
|
||||
|
|
|
@ -71,21 +71,21 @@ NODE_PROC(RevolvingDiscs, revolving_discs_data)
|
|||
{
|
||||
sacn_pixel Color = PackFloatsToSACNPixel(Data->Color.r, Data->Color.g, Data->Color.b);
|
||||
|
||||
v3 Center = v3{0, 0, 0};
|
||||
v3 Normal = v3{GSCos(Data->ThetaZ), 0, GSSin(Data->ThetaZ)}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
||||
v3 Right = Cross(Normal, v3{0, 1, 0});
|
||||
v4 Center = v4{0, 0, 0, 1};
|
||||
v4 Normal = v4{GSCos(Data->ThetaZ), 0, GSSin(Data->ThetaZ), 0}; // NOTE(Peter): dont' need to normalize. Should always be 1
|
||||
v4 Right = Cross(Normal, v4{0, 1, 0, 0});
|
||||
//Normal = RotateAround(Data->ThetaY, Right);
|
||||
|
||||
v3 FrontCenter = Center + (Normal * Data->DiscWidth);
|
||||
v3 BackCenter = Center - (Normal * Data->DiscWidth);
|
||||
v4 FrontCenter = Center + (Normal * Data->DiscWidth);
|
||||
v4 BackCenter = Center - (Normal * Data->DiscWidth);
|
||||
|
||||
led* LED = Data->ResultLEDs;
|
||||
for (s32 l = 0; l < Data->ResultLEDCount; l++)
|
||||
{
|
||||
v3 Position = LED->Position;
|
||||
v4 Position = LED->Position;
|
||||
|
||||
v3 ToFront = Normalize(Position + FrontCenter);
|
||||
v3 ToBack = Normalize(Position + BackCenter);
|
||||
v4 ToFront = Normalize(Position + FrontCenter);
|
||||
v4 ToBack = Normalize(Position + BackCenter);
|
||||
|
||||
r32 ToFrontDotNormal = Dot(ToFront, Normal);
|
||||
r32 ToBackDotNormal = Dot(ToBack, Normal);
|
||||
|
|
|
@ -516,7 +516,7 @@ INT NCmdShow
|
|||
r32 LastFrameSecondsElapsed = 0.0f;
|
||||
|
||||
GlobalDebugServices = (debug_services*)malloc(sizeof(debug_services));
|
||||
InitDebugServices(GlobalDebugServices, (u8*)malloc(Megabytes(8)), Megabytes(8), 1000, PerformanceCountFrequency);
|
||||
InitDebugServices(GlobalDebugServices, (u8*)malloc(Megabytes(8)), Megabytes(16), 32000, PerformanceCountFrequency);
|
||||
GlobalDebugServices->GetWallClock = GetWallClock;
|
||||
|
||||
mouse_state Mouse;
|
||||
|
|
27
todo.txt
27
todo.txt
|
@ -1,8 +1,21 @@
|
|||
TODO FOLDHAUS
|
||||
|
||||
|
||||
BUGS
|
||||
- Typing a period into a float value doesn't register. Problem here is that we arent' translating key presses into characters at the win32 layer. Need to do that.
|
||||
|
||||
Switch To Nodes
|
||||
- separate node functionality from drawing the nodes
|
||||
- - parallelize the node connections array so that they can be pushed and freed independently
|
||||
- - this could allow dynamically resizing node connections
|
||||
- - separate out interface nodes from computation nodes (interface in a binary/quad tree?)
|
||||
- - Investigate why we're giving nodes bounds :NodesDontNeedToKnowTheirBounds
|
||||
- selector node (has a list of connections that it can switch between)
|
||||
- delete nodes
|
||||
- remove node connections
|
||||
- Serialize Nodes
|
||||
- evaluation step (one node at a time)
|
||||
|
||||
Hardening
|
||||
- turn the default sculpture view into an operation mode ? (have to think about this)
|
||||
- Then we want to think about separating out mode render functions from mode update functions. Not sure its necessary but having something that operates like an update funciton but is called render is weird. Might want some sort of coroutine functionality in place, where modes can add and remove optional, parallel
|
||||
|
@ -16,17 +29,10 @@ update functions
|
|||
UI Improvements
|
||||
- highlight node field under active edit
|
||||
- draw cursor in node field under active edit
|
||||
x print node field names on hover or on the node
|
||||
- Mouse Held Commands
|
||||
- Actual cursor states
|
||||
|
||||
API Improvements
|
||||
x Clean up DrawString... good lord
|
||||
x Add Text Alignment to DrawString
|
||||
- Investigate why we're giving nodes bounds :NodesDontNeedToKnowTheirBounds
|
||||
- - Cant we just calculate this at render time?
|
||||
- Move nodes over to referencing eachother based on a UID system
|
||||
- separate out interface nodes from computation nodes (interface in a binary/quad tree?)
|
||||
|
||||
Application
|
||||
- More efficient HSV <-> RGB
|
||||
|
@ -46,13 +52,6 @@ Interface
|
|||
- Scroll view
|
||||
- Update the text system - use system fonts
|
||||
|
||||
Switch To Nodes
|
||||
- selector node (has a list of connections that it can switch between)
|
||||
- delete nodes
|
||||
- remove node connections
|
||||
- Serialize Nodes
|
||||
- evaluation step (one node at a time)
|
||||
|
||||
Structure
|
||||
- motion
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
BUGS
|
||||
x if there is nothing in the filtered list when searching for a node, hitting enter still selects one
|
||||
x Search lister - returning from a filtered list that has zero elements to one that has a few, hotItem = -1
|
||||
|
||||
Intermediate Lifetime Memory & Operations
|
||||
x Intermediate lifetime memory arena
|
||||
|
@ -17,6 +18,14 @@ x and manually adding each command, store the commands as an array, and auto i
|
|||
x push the mode on the mode stack
|
||||
x decided I don't like storing NodeRenderSettings in each operation mode. Probably want to put it back in x app_state
|
||||
|
||||
UI Improvements
|
||||
x print node field names on hover or on the node
|
||||
|
||||
API Improvements
|
||||
x Clean up DrawString... good lord
|
||||
x Add Text Alignment to DrawString
|
||||
x Move nodes over to referencing eachother based on a UID system
|
||||
|
||||
/Debug
|
||||
x Make debug scope tracking thread safe - was throwing an error in stringsequal but that stopped.
|
||||
x Keep an eye out.
|
||||
|
|
Loading…
Reference in New Issue