diff --git a/.gitignore b/.gitignore index d163863..1661771 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -build/ \ No newline at end of file +build/ +release/ \ No newline at end of file diff --git a/brightness.txt b/brightness.txt index e69de29..2d6c51f 100644 --- a/brightness.txt +++ b/brightness.txt @@ -0,0 +1,45 @@ +UI_Column() + { + UI_Spacer(UI_Em(1, 1)); + UI_Height(UI_Em(1, 1)) UI_Row() + { + UI_Width(UI_TextContent(15, 1)) UI_LabelF("Scrollbar T:"); + + UI_SetNextWidth(UI_Em(20, 1)); + UI_SetNextCornerRadius(UI_TopFontSize()*0.5f); + ui_box *Container = UI_MakeBoxF(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder, "Scrollable"); + UI_Parent(Container) + { + UI_SetNextCornerRadius(UI_TopFontSize()*0.5f); + UI_SetNextSize(UI_Em(1, 1), UI_Em(1, 1)); + UI_SetNextFixedX((DimOfRange(Container->Rect).x-UI_TopFontSize())*ScrollbarT); + ui_box *Box = UI_MakeBoxF(UI_BoxFlag_DrawBackground| + UI_BoxFlag_DrawBorder| + UI_BoxFlag_HotAnimation| + UI_BoxFlag_ActiveAnimation| + UI_BoxFlag_Clickable| + UI_BoxFlag_FloatingX| + 0, "Dragable"); + ui_signal Signal = UI_SignalFromBox(Box); + if(Signal.Dragging) + { + if(Signal.Pressed) + { + UI_StoreDragR32(ScrollbarT); + } + + r32 StartT = UI_GetDragR32(); + r32 EndT = StartT + Signal.DragDelta.x/(DimOfRange(Container->Rect).x-UI_TopFontSize()); + ScrollbarT = Clamp01(EndT); + } + } + + UI_Width(UI_TextContent(30, 1)) UI_Height(UI_Em(2, 1)) + { + if(UI_ButtonF("Reset Dialog").Pressed) + { + Time = 0.0f; + } + } + } + } \ No newline at end of file diff --git a/code/build.bat b/code/build.bat index 4e531b8..5c01563 100644 --- a/code/build.bat +++ b/code/build.bat @@ -10,4 +10,5 @@ codegen ../code/ cl %CommonCompilerOptions% ../code/vn.cpp /LD /link /export:VN_UpdateAndRender /incremental:no cl %CommonCompilerOptions% ../code/win32_main.cpp /link user32.lib gdi32.lib winmm.lib opengl32.lib + popd \ No newline at end of file diff --git a/code/build_win32.bat b/code/build_win32.bat new file mode 100644 index 0000000..73765ed --- /dev/null +++ b/code/build_win32.bat @@ -0,0 +1,16 @@ +@echo off + +set CommonCompilerOptions=/Zi /FC /nologo /DW32_LINK_SINGLE=1 /DVN_INTERNAL=0 /DVN_SLOW=0 /DVN_USE_INSTANCING=1 /O2 /W4 /WX /we4062 /wd4996 /wd4201 /wd4305 /wd4244 /wd4100 /wd4505 /std:c++17 + +if not exist "../release" mkdir "../release" + +pushd "../release/" +rem cl /Zi /nologo /FC ../code/third_party/codegen/codegen.c +"../build/codegen" ../code/ + +cl %CommonCompilerOptions% ../code/win32_main.cpp /link user32.lib gdi32.lib winmm.lib opengl32.lib + +xcopy /y /q win32_main.exe vn.exe +del win32_main.* + del *.pdb +popd \ No newline at end of file diff --git a/code/build_win32_asan.bat b/code/build_win32_asan.bat new file mode 100644 index 0000000..cab76e5 --- /dev/null +++ b/code/build_win32_asan.bat @@ -0,0 +1,11 @@ +@echo off + +set CommonCompilerOptions=/fsanitize=address /Zi /FC /nologo /DVN_ASAN_ENABLED=1 /DW32_LINK_SINGLE=1 /DVN_INTERNAL=1 /DVN_SLOW=1 /DVN_USE_INSTANCING=1 /Oi /W4 /WX /we4062 /wd4996 /wd4201 /wd4305 /wd4244 /wd4100 /wd4505 /std:c++17 + +if not exist "../build" mkdir "../build" + +pushd "../build/" +rem cl /Zi /nologo /FC ../code/third_party/codegen/codegen.c +codegen ../code/ +cl %CommonCompilerOptions% ../code/win32_main.cpp /link user32.lib gdi32.lib winmm.lib opengl32.lib /subsystem:console +popd \ No newline at end of file diff --git a/code/core/core.h b/code/core/core.h index b063622..9934a61 100644 --- a/code/core/core.h +++ b/code/core/core.h @@ -222,8 +222,8 @@ inline void EndTicketMutex(ticket_mutex *Mutex) //- sixten: Axes enum axis2 { - Axis2_X, - Axis2_Y, + Axis2_X = 0, + Axis2_Y = 1, Axis2_Count }; diff --git a/code/core/core_math.cpp b/code/core/core_math.cpp index f669061..7155e05 100644 --- a/code/core/core_math.cpp +++ b/code/core/core_math.cpp @@ -631,8 +631,14 @@ inline range2_r32 Intersection(range2_r32 A, range2_r32 B) inline v2_r32 CornerFromRange(range2_r32 Range, corner Corner) { - v2_r32 Result = V2R32((Corner & (1 << Axis2_X))?Range.Min.x:Range.Max.x, - (Corner & (1 << Axis2_Y))?Range.Min.y:Range.Max.y); + v2_r32 Result = V2R32((Corner & (1 << Axis2_X))?Range.Max.x:Range.Min.x, + (Corner & (1 << Axis2_Y))?Range.Max.y:Range.Min.y); + return(Result); +} + +inline range2_r32 Pad(range2_r32 Range, v2_r32 Value) +{ + range2_r32 Result = Range2R32(Range.Min-Value, Range.Max+Value); return(Result); } @@ -670,8 +676,8 @@ inline range2_s32 Intersection(range2_s32 A, range2_s32 B) inline v2_s32 CornerFromRange(range2_s32 Range, corner Corner) { - v2_s32 Result = V2S32((Corner & (1 << Axis2_X))?Range.Min.x:Range.Max.x, - (Corner & (1 << Axis2_Y))?Range.Min.y:Range.Max.y); + v2_s32 Result = V2S32((Corner & (1 << Axis2_X))?Range.Max.x:Range.Min.x, + (Corner & (1 << Axis2_Y))?Range.Max.y:Range.Min.y); return(Result); } @@ -709,7 +715,7 @@ inline range2_s64 Intersection(range2_s64 A, range2_s64 B) inline v2_s64 CornerFromRange(range2_s64 Range, corner Corner) { - v2_s64 Result = V2S64((Corner & (1 << Axis2_X))?Range.Min.x:Range.Max.x, - (Corner & (1 << Axis2_Y))?Range.Min.y:Range.Max.y); + v2_s64 Result = V2S64((Corner & (1 << Axis2_X))?Range.Max.x:Range.Min.x, + (Corner & (1 << Axis2_Y))?Range.Max.y:Range.Min.y); return(Result); } \ No newline at end of file diff --git a/code/core/core_math.h b/code/core/core_math.h index e63b9ac..c1404a6 100644 --- a/code/core/core_math.h +++ b/code/core/core_math.h @@ -355,6 +355,7 @@ inline b32 Contains(range2_r32 Range, v2_r32 Value); inline v2_r32 DimOfRange(range2_r32 Range); inline range2_r32 Intersection(range2_r32 A, range2_r32 B); inline v2_r32 CornerFromRange(range2_r32 Range, corner Corner); +inline range2_r32 Pad(range2_r32 Range, v2_r32 Value); inline range2_s32 Range2S32(v2_s32 A, v2_s32 B); inline b32 InRange(range2_s32 Range, v2_s32 Value); diff --git a/code/core/core_memory.cpp b/code/core/core_memory.cpp index 3ed1392..9a27509 100644 --- a/code/core/core_memory.cpp +++ b/code/core/core_memory.cpp @@ -42,90 +42,192 @@ static void Fill(void *Dest, u8 Value, umm Count) } } +#if VN_ASAN_ENABLED +#include +#endif + //////////////////////////////// //- sixten: Memory Arena Functions -static memory_arena *ArenaAllocate(u64 Size) +static arena *ArenaAlloc(u64 Size, b32 Chaining) { - u64 RoundedSize = Size+Megabytes(64)-1; - RoundedSize -= RoundedSize&Megabytes(64); - void *Memory = Platform.Reserve(RoundedSize); - u64 InitialCommitSize = MEMORY_ARENA_COMMIT_SIZE; - Platform.Commit(Memory, InitialCommitSize); - memory_arena *Arena = (memory_arena *)Memory; - Arena->Position = sizeof(memory_arena); - Arena->CommitPosition = InitialCommitSize; + arena *Arena = 0; + if(Chaining) + { + void *Memory = Platform.Allocate(Size); + Arena = (arena *)Memory; + +#if VN_ASAN_ENABLED + ASAN_POISON_MEMORY_REGION(Arena, Size); + ASAN_UNPOISON_MEMORY_REGION(Arena, sizeof(arena)); +#endif + + Arena->Chaining = true; + SenDLLInit(Arena); + + } + else + { + u64 RoundedSize = Size+Megabytes(64)-1; + RoundedSize -= RoundedSize&Megabytes(64); + void *Memory = Platform.Reserve(RoundedSize); + u64 InitialCommitSize = MEMORY_ARENA_COMMIT_SIZE; + Platform.Commit(Memory, InitialCommitSize); + Arena = (arena *)Memory; + } + Arena->Position = sizeof(arena); Arena->Size = Size; Arena->Align = 8; return(Arena); } -static void ArenaRelease(memory_arena *Arena) +static void ArenaRelease(arena *Arena) { - Platform.Release(Arena); + if(Arena->Chaining) + { + arena *Node = Arena->Prev; + for(;Node != Arena;) + { + arena *Next = Node->Prev; + Platform.Deallocate(Node); + Node = Next; + } +#if VN_ASAN_ENABLED + ASAN_POISON_MEMORY_REGION(Arena, Arena->Size); +#endif + Platform.Deallocate(Arena); + } + else + { + Platform.Release(Arena); + } } -static void *ArenaPushNoClear(memory_arena *Arena, u64 Size) +static void *ArenaPushNoClear(arena *Arena, u64 Size) { void *Result = 0; - if(Arena->Position + Size <= Arena->Size) + if(Arena->Chaining) { - u8 *Base = (u8 *)Arena; - u64 PostAlignPos = (Arena->Position+Arena->Align-1); - PostAlignPos -= PostAlignPos%Arena->Align; - u64 Align = PostAlignPos - Arena->Position; - Result = Base + Arena->Position + Align; - Arena->Position += Size + Align; - if(Arena->CommitPosition < Arena->Position) + if(Size <= Arena->Size) { - u64 ToCommit = Arena->Position - Arena->CommitPosition; - ToCommit += MEMORY_ARENA_COMMIT_SIZE - 1; - ToCommit -= ToCommit%MEMORY_ARENA_COMMIT_SIZE; - Platform.Commit(Base + Arena->CommitPosition, ToCommit); - Arena->CommitPosition += ToCommit; + arena *Target = Arena->Prev; // sixten: We always append to the end of the list. + if(Target->Position + Size > Target->Size) + { + arena *New = ArenaAlloc(Arena->Size, true); + New->NotFirst = true; + SenDLLInsertLast(Arena, New); + Target = New; + } + u8 *Base = (u8 *)Target; + u64 PostAlignPos = (Target->Position+Target->Align-1); + PostAlignPos -= PostAlignPos%Target->Align; + Result = Base + PostAlignPos; + Target->Position = PostAlignPos+Size; + +#if VN_ASAN_ENABLED + ASAN_UNPOISON_MEMORY_REGION(Result, Size); +#endif + } + else + { + // sixten(NOTE): We can't really do anything in this situation. } } else { - InvalidCodepath; + if(Arena->Position + Size <= Arena->Size) + { + u8 *Base = (u8 *)Arena; + u64 PostAlignPos = (Arena->Position+Arena->Align-1); + PostAlignPos -= PostAlignPos%Arena->Align; + u64 Align = PostAlignPos - Arena->Position; + Result = Base + Arena->Position + Align; + Arena->Position += Size + Align; + if(Arena->CommitPosition < Arena->Position) + { + u64 ToCommit = Arena->Position - Arena->CommitPosition; + ToCommit += MEMORY_ARENA_COMMIT_SIZE - 1; + ToCommit -= ToCommit%MEMORY_ARENA_COMMIT_SIZE; + Platform.Commit(Base + Arena->CommitPosition, ToCommit); + Arena->CommitPosition += ToCommit; + } + } + else + { + InvalidCodepath; + } } return(Result); } -static void *ArenaPush(memory_arena *Arena, u64 Size) +static void *ArenaPush(arena *Arena, u64 Size) { void *Result = ArenaPushNoClear(Arena, Size); Fill(Result, 0, Size); return(Result); } -static void ArenaPopTo(memory_arena *Arena, u64 Position) +static void ArenaPopTo(arena *Arena, u64 Position) { - u64 MinPosition = sizeof(*Arena); - u64 NewPosition = Maximum(MinPosition, Position); - Arena->Position = NewPosition; - u64 CommitAlignedPosition = Arena->Position+MEMORY_ARENA_COMMIT_SIZE-1; - CommitAlignedPosition -= CommitAlignedPosition%MEMORY_ARENA_COMMIT_SIZE; - if(CommitAlignedPosition + MEMORY_ARENA_DECOMMIT_THRESHOLD <= Arena->CommitPosition) + if(Arena->Chaining) { - u8 *Base = (u8 *)Arena; - u64 ToDecommit = Arena->CommitPosition-CommitAlignedPosition; - Platform.Decommit(Base+CommitAlignedPosition, ToDecommit); - Arena->CommitPosition -= ToDecommit; + // sixten: find the relevant arena + arena *Target = Arena; + for(int ArenaIndex = 0; ArenaIndex < Position/Arena->Size; ++ArenaIndex) + { + Target = Arena->Next; + } + + // sixten: deallocate all arenas that are no longer needed + { + arena *Node = Arena->Prev; + while(Node != Target) + { + arena *Prev = Node->Prev; + SenDLLRemove(Node); +#if VN_ASAN_ENABLED + ASAN_POISON_MEMORY_REGION(Node, Node->Size); +#endif + Platform.Deallocate(Node); + Node = Prev; + } + } + + Target->Position = Position%Arena->Size; +#if VN_ASAN_ENABLED + u64 UnpoisonPosition = Target->Position; + ASAN_POISON_MEMORY_REGION(Target, Target->Size); + ASAN_UNPOISON_MEMORY_REGION(Target, UnpoisonPosition); +#endif + } + else + { + u64 MinPosition = sizeof(*Arena); + u64 NewPosition = Maximum(MinPosition, Position); + Arena->Position = NewPosition; + u64 CommitAlignedPosition = Arena->Position+MEMORY_ARENA_COMMIT_SIZE-1; + CommitAlignedPosition -= CommitAlignedPosition%MEMORY_ARENA_COMMIT_SIZE; + if(CommitAlignedPosition + MEMORY_ARENA_DECOMMIT_THRESHOLD <= Arena->CommitPosition) + { + u8 *Base = (u8 *)Arena; + u64 ToDecommit = Arena->CommitPosition-CommitAlignedPosition; + Platform.Decommit(Base+CommitAlignedPosition, ToDecommit); + Arena->CommitPosition -= ToDecommit; + } } } -static void ArenaPop(memory_arena *Arena, u64 Amount) +static void ArenaPop(arena *Arena, u64 Amount) { - ArenaPopTo(Arena, Max(Arena->Position-Amount, (s64)sizeof(memory_arena))); + ArenaPopTo(Arena, Max(Arena->Position-Amount, (s64)sizeof(arena))); } -static void ArenaClear(memory_arena *Arena) +static void ArenaClear(arena *Arena) { ArenaPopTo(Arena, sizeof(*Arena)); } -static void ArenaSetAlign(memory_arena *Arena, u64 Align) +static void ArenaSetAlign(arena *Arena, u64 Align) { Arena->Align = Align; } @@ -133,7 +235,7 @@ static void ArenaSetAlign(memory_arena *Arena, u64 Align) //////////////////////////////// //- sixten: Temporary Memory Functions -static temporary_memory BeginTemporaryMemory(memory_arena *Arena) +static temporary_memory BeginTemporaryMemory(arena *Arena) { temporary_memory Temp; Temp.Arena = Arena; diff --git a/code/core/core_memory.h b/code/core/core_memory.h index 4d047aa..eb3c48f 100644 --- a/code/core/core_memory.h +++ b/code/core/core_memory.h @@ -3,6 +3,23 @@ #ifndef CORE_MEMORY_H #define CORE_MEMORY_H +/* +The arenas can be used in two modes: +1. Fixed Size: +This is primarily intended for when you need a contigous buffer of memory, it reserves a large chunk +of virtual address space (if applicable) and partitions it to the user. + +2. Chaining: +This is the workaround for WASM not supporting memory mapping. It allocates in chunks based on the initial +size requested in the ArenaAlloc call. Internally it just consists of a cyclic doubly linked list. + +Potential alternatives: +If you pass in a size of 0 in ArenaAlloc, you get a chaining arena with set chunk size that can extend if +a PushSize call requests more than the prespecified standard. (ex. 4KB chunks, but if you load a file then +that becomes its own chunk) + +*/ + //////////////////////////////// //- sixten: Common Memory Functions @@ -15,18 +32,22 @@ static void Fill(void *Dest, u8 Value, umm Count); //////////////////////////////// //- sixten: Memory Arena Types -struct memory_arena +struct arena { u64 Position; u64 CommitPosition; u64 Size; u64 Align; - u64 Unused[4]; + b32 Chaining; + b32 NotFirst; + arena *Next; + arena *Prev; + u64 Unused[1]; }; struct temporary_memory { - memory_arena *Arena; + arena *Arena; u64 Position; }; @@ -38,14 +59,14 @@ struct temporary_memory //////////////////////////////// //- sixten: Memory Arena Functions -static memory_arena *ArenaAllocate(u64 Size); -static void ArenaRelease(memory_arena *Arena); -static void *ArenaPushNoClear(memory_arena *Arena, u64 Size); -static void *ArenaPush(memory_arena *Arena, u64 Size); -static void ArenaPopTo(memory_arena *Arena, u64 Position); -static void ArenaPop(memory_arena *Arena, u64 Amount); -static void ArenaClear(memory_arena *Arena); -static void ArenaSetAlign(memory_arena *Arena, u64 Align); +static arena *ArenaAlloc(u64 Size, b32 Chaining = false); +static void ArenaRelease(arena *Arena); +static void *ArenaPushNoClear(arena *Arena, u64 Size); +static void *ArenaPush(arena *Arena, u64 Size); +static void ArenaPopTo(arena *Arena, u64 Position); +static void ArenaPop(arena *Arena, u64 Amount); +static void ArenaClear(arena *Arena); +static void ArenaSetAlign(arena *Arena, u64 Align); #define PushArray(Arena, type, Count) (type *)ArenaPush((Arena), sizeof(type)*(Count)) #define PushArrayNoClear(Arena, type, Count) (type *)ArenaPushNoClear((Arena), sizeof(type)*(Count)) #define PushStruct(Arena, type) (type *)ArenaPush((Arena), sizeof(type)) @@ -54,7 +75,7 @@ static void ArenaSetAlign(memory_arena *Arena, u64 Align); //////////////////////////////// //- sixten: Temporary Memory Functions -static temporary_memory BeginTemporaryMemory(memory_arena *Arena); +static temporary_memory BeginTemporaryMemory(arena *Arena); static void EndTemporaryMemory(temporary_memory Temp); #endif //CORE_MEMORY_H diff --git a/code/core/core_string.cpp b/code/core/core_string.cpp index 5ff771a..ca7825a 100644 --- a/code/core/core_string.cpp +++ b/code/core/core_string.cpp @@ -195,7 +195,7 @@ static s64 LastIndexOf(string String, string Sub) //- sixten: Allocation -static string PushString(memory_arena *Arena, string String) +static string PushString(arena *Arena, string String) { string Result; Result.Data = PushArrayNoClear(Arena, u8, String.Count); @@ -205,7 +205,7 @@ static string PushString(memory_arena *Arena, string String) return(Result); } -static string PushFormatVariadic(memory_arena *Arena, char *Format, va_list Arguments) +static string PushFormatVariadic(arena *Arena, char *Format, va_list Arguments) { va_list ArgumentsCopy; va_copy(ArgumentsCopy, Arguments); @@ -220,7 +220,7 @@ static string PushFormatVariadic(memory_arena *Arena, char *Format, va_list Argu return(Result); } -static string PushFormat(memory_arena *Arena, char *Format, ...) +static string PushFormat(arena *Arena, char *Format, ...) { va_list Arguments; va_start(Arguments, Format); @@ -230,7 +230,7 @@ static string PushFormat(memory_arena *Arena, char *Format, ...) return(Result); } -static string PushCString(memory_arena *Arena, char *CString) +static string PushCString(arena *Arena, char *CString) { string String = MakeString(CString); string Result = PushString(Arena, String); @@ -266,7 +266,7 @@ static s64 ConvertStringToS64(string String) return(Result); } -static string ConvertS64ToString(memory_arena *Arena, s64 Value) +static string ConvertS64ToString(arena *Arena, s64 Value) { b32 IsNegative = (Value < 0); if(IsNegative) @@ -297,7 +297,7 @@ static string ConvertS64ToString(memory_arena *Arena, s64 Value) return(String); } -static string StringFromCodepoint(memory_arena *Arena, u32 Codepoint) +static string StringFromCodepoint(arena *Arena, u32 Codepoint) { char Buffer[5] = {}; UTF8FromCodepoint((u8 *)Buffer, Codepoint); @@ -317,7 +317,7 @@ static r64 DoubleFromString(string String) //- sixten: Replacing -static string RemoveAll(memory_arena *Arena, string Text, char ToRemove) +static string RemoveAll(arena *Arena, string Text, char ToRemove) { //- sixten: get new count s64 Occurrences = 0; @@ -377,7 +377,7 @@ static s64 StringLength16(u16 *String) //~ sixten: String list -static void AppendString(string_list *List, string String, memory_arena *Arena) +static void AppendString(string_list *List, string String, arena *Arena) { string_node *Node = PushStruct(Arena, string_node); Node->String = String; @@ -387,7 +387,7 @@ static void AppendString(string_list *List, string String, memory_arena *Arena) DLLInsertLast(List->First, List->Last, Node); } -static string JoinStringList(string_list *List, memory_arena *Arena) +static string JoinStringList(string_list *List, arena *Arena) { u8 *Buffer = PushArray(Arena, u8, List->TotalCount + 1); Buffer[List->TotalCount] = 0; @@ -420,7 +420,7 @@ static string_chunk_list MakeStringChunkList(s64 ChunkSize) return(Result); } -static string JoinStringChunkList(memory_arena *Arena, string_chunk_list *List) +static string JoinStringChunkList(arena *Arena, string_chunk_list *List) { string Result = {}; Result.Count = List->TotalCount; @@ -438,7 +438,7 @@ static string JoinStringChunkList(memory_arena *Arena, string_chunk_list *List) } // sixten(TODO): Incomplete, remove maybe? -static void ReplaceRange(memory_arena *Arena, string_chunk_list *List, string Text, range1_s64 Range) +static void ReplaceRange(arena *Arena, string_chunk_list *List, string Text, range1_s64 Range) { s64 NewTotalCount = Max(0ULL, List->TotalCount - DimOfRange(Range)) + Text.Count; @@ -714,7 +714,7 @@ static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint) return(Length); } -static string String8FromString16(memory_arena *Arena, string16 String) +static string String8FromString16(arena *Arena, string16 String) { s64 AllocGuess = String.Count*3+1; u8 *Memory = PushArray(Arena, u8, AllocGuess); @@ -738,7 +738,7 @@ static string String8FromString16(memory_arena *Arena, string16 String) return(Result); } -static string16 String16FromString8(memory_arena *Arena, string String) +static string16 String16FromString8(arena *Arena, string String) { s64 AllocGuess = String.Count*2+1; u16 *Memory = PushArray(Arena, u16, AllocGuess); @@ -843,7 +843,7 @@ static text_range TextRange(text_point A, text_point B) //////////////////////////////// //~ sixten: 1D Interval List & Array Functions -static void Range1S64ListPush(memory_arena *Arena, range1_s64_list *List, range1_s64 Range) +static void Range1S64ListPush(arena *Arena, range1_s64_list *List, range1_s64 Range) { range1_s64_node *Node = PushStructNoClear(Arena, range1_s64_node); Node->Range = Range; @@ -851,7 +851,7 @@ static void Range1S64ListPush(memory_arena *Arena, range1_s64_list *List, range1 List->Count += 1; } -static range1_s64_array Range1S64ArrayFromList(memory_arena *Arena, range1_s64_list *List) +static range1_s64_array Range1S64ArrayFromList(arena *Arena, range1_s64_list *List) { range1_s64_array Result = {}; Result.Count = List->Count; diff --git a/code/core/core_string.h b/code/core/core_string.h index a8dcc9d..87246a1 100644 --- a/code/core/core_string.h +++ b/code/core/core_string.h @@ -93,21 +93,21 @@ static s64 LastIndexOf(string String, string Sub); //- sixten: Allocation -static string PushString(memory_arena *Arena, string String); -static string PushFormatVariadic(memory_arena *Arena, char *Format, va_list Arguments); -static string PushFormat(memory_arena *Arena, char *Format, ...); -static string PushCString(memory_arena *Arena, char *String); +static string PushString(arena *Arena, string String); +static string PushFormatVariadic(arena *Arena, char *Format, va_list Arguments); +static string PushFormat(arena *Arena, char *Format, ...); +static string PushCString(arena *Arena, char *String); //- sixten: Conversion static s64 ConvertStringToS64(string String); -static string ConvertS64ToString(memory_arena *Arena, s64 Value); -static string StringFromCodepoint(memory_arena *Arena, u32 Codepoint); +static string ConvertS64ToString(arena *Arena, s64 Value); +static string StringFromCodepoint(arena *Arena, u32 Codepoint); static r64 DoubleFromString(string String); //- sixten: Replacing -static string RemoveAll(memory_arena *Arena, string Text, char ToRemove); +static string RemoveAll(arena *Arena, string Text, char ToRemove); //- sixten: "C Style" strings @@ -115,18 +115,10 @@ static s64 StringLength(char *String); static s64 StringLength16(u16 *String); -#if 0 -///////////////////////////////////// -//~ sixten: String Chunk Functions -static string_chunk_list MakeStringChunkList(s64 ChunkSize); -static string JoinStringChunkList(memory_arena *Arena, string_chunk_list *List); -static void ReplaceRange(memory_arena *Arena, string_chunk_list *List, string Text, range1_s64 Range); -#endif - //~ sixten: String list -static void AppendString(string_list *List, string String, memory_arena *Arena); -static string JoinStringList(string_list *List, memory_arena *Arena); +static void AppendString(string_list *List, string String, arena *Arena); +static string JoinStringList(string_list *List, arena *Arena); //~ sixten: Unicode @@ -145,8 +137,8 @@ static u32 EncodeUTF16Codepoint(u16 *Dest, u32 Codepoint); static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint); -static string String8FromString16(memory_arena *Arena, string16 String); -static string16 String16FromString8(memory_arena *Arena, string String); +static string String8FromString16(arena *Arena, string16 String); +static string16 String16FromString8(arena *Arena, string String); //~ sixten: Text point @@ -190,8 +182,8 @@ struct range1_s64_array //////////////////////////////// //~ sixten: 1D Interval List & Array Functions -static void Range1S64ListPush(memory_arena *Arena, range1_s64_list *List, range1_s64 Range); -static range1_s64_array Range1S64ArrayFromList(memory_arena *Arena, range1_s64_list *List); +static void Range1S64ListPush(arena *Arena, range1_s64_list *List, range1_s64 Range); +static range1_s64_array Range1S64ArrayFromList(arena *Arena, range1_s64_list *List); static s64 OffsetFromTextPoint(string Text, range1_s64_array Lines, text_point Point); #endif //CORE_STRING_H diff --git a/code/core/core_thread_context.cpp b/code/core/core_thread_context.cpp index eedd61f..84ede7f 100644 --- a/code/core/core_thread_context.cpp +++ b/code/core/core_thread_context.cpp @@ -5,7 +5,7 @@ static thread_context AllocateThreadContext(void) thread_context Context = {}; for(s64 ArenaIndex = 0; ArenaIndex < ArrayCount(Context.Arenas); ArenaIndex += 1) { - Context.Arenas[ArenaIndex] = ArenaAllocate(Gigabytes(1)); + Context.Arenas[ArenaIndex] = ArenaAlloc(Megabytes(2), true); } return(Context); } @@ -20,7 +20,7 @@ static thread_context *GetThreadContext(void) return(ThreadLocal_ThreadContext); } -static temporary_memory GetScratch(memory_arena **Conflicts, u64 ConflictCount) +static temporary_memory GetScratch(arena **Conflicts, u64 ConflictCount) { temporary_memory Scratch = {}; thread_context *Context = GetThreadContext(); @@ -34,7 +34,7 @@ static temporary_memory GetScratch(memory_arena **Conflicts, u64 ConflictCount) ConflictIndex < ConflictCount; ++ConflictIndex) { - memory_arena *Conflict = Conflicts[ConflictIndex]; + arena *Conflict = Conflicts[ConflictIndex]; if(Conflict == Context->Arenas[ArenaIndex]) { FoundConflict = true; diff --git a/code/core/core_thread_context.h b/code/core/core_thread_context.h index e54a8e7..f16d15c 100644 --- a/code/core/core_thread_context.h +++ b/code/core/core_thread_context.h @@ -5,7 +5,7 @@ struct thread_context { - memory_arena *Arenas[2]; + arena *Arenas[2]; }; //- sixten: Thread state management @@ -13,7 +13,7 @@ static void SetThreadContext(thread_context *Context); static thread_context *GetThreadContext(void); //- sixten: Scratch -static temporary_memory GetScratch(memory_arena **Conflicts = 0, u64 ConflictCount = 0); +static temporary_memory GetScratch(arena **Conflicts = 0, u64 ConflictCount = 0); #define ReleaseScratch(Scratch) EndTemporaryMemory(Scratch) #endif //CORE_THREAD_CONTEXT_H diff --git a/code/generated/vn_character.meta.c b/code/generated/vn_character.meta.c index fca3daf..bc8c7c1 100644 --- a/code/generated/vn_character.meta.c +++ b/code/generated/vn_character.meta.c @@ -5,6 +5,7 @@ if(0) {} else if(AreEqual(String, StrLit("none"))) { Result = CR_State_None; } else if(AreEqual(String, StrLit("normal"))) { Result = CR_State_Normal; } else if(AreEqual(String, StrLit("happy"))) { Result = CR_State_Happy; } +else if(AreEqual(String, StrLit("leaning"))) { Result = CR_State_Leaning; } return(Result); } diff --git a/code/generated/vn_character.meta.h b/code/generated/vn_character.meta.h index f9be9a4..b010f7a 100644 --- a/code/generated/vn_character.meta.h +++ b/code/generated/vn_character.meta.h @@ -4,5 +4,6 @@ CR_State_Invalid = 0, CR_State_None, CR_State_Normal, CR_State_Happy, +CR_State_Leaning, }; diff --git a/code/generated/vn_platform.meta.h b/code/generated/vn_platform.meta.h index b4ad352..ecec7f0 100644 --- a/code/generated/vn_platform.meta.h +++ b/code/generated/vn_platform.meta.h @@ -2,6 +2,8 @@ #define PLATFORM_RELEASE(name) void name(void *Pointer) #define PLATFORM_COMMIT(name) void name(void *Pointer, u64 Size) #define PLATFORM_DECOMMIT(name) void name(void *Pointer, u64 Size) +#define PLATFORM_ALLOCATE(name) void * name(u64 Size) +#define PLATFORM_DEALLOCATE(name) void name(void *Pointer) #define PLATFORM_OPEN_FILE(name) platform_file_handle name(string Path, platform_access_flags FileAccess) #define PLATFORM_CLOSE_FILE(name) void name(platform_file_handle Handle) #define PLATFORM_READ_FILE(name) void name(platform_file_handle Handle, void *Dest, u64 Offset, u64 Size) @@ -10,16 +12,18 @@ #define PLATFORM_SET_CURSOR(name) void name(platform_cursor Cursor) #define PLATFORM_TOGGLE_FULLSCREEN(name) void name(void) #define PLATFORM_SHOW_MESSAGE(name) void name(string Message, platform_message_type Type) -#define PLATFORM_BEGIN_FILE_ITER(name) platform_file_iter * name(memory_arena *Arena, string Path) -#define PLATFORM_ADVANCE_FILE_ITER(name) b32 name(memory_arena *Arena, platform_file_iter *Iter, platform_file_info *OutInfo) +#define PLATFORM_BEGIN_FILE_ITER(name) platform_file_iter * name(arena *Arena, string Path) +#define PLATFORM_ADVANCE_FILE_ITER(name) b32 name(arena *Arena, platform_file_iter *Iter, platform_file_info *OutInfo) #define PLATFORM_END_FILE_ITER(name) void name(platform_file_iter *Iter) #define PLATFORM_SET_CLIPBOARD(name) void name(string String) -#define PLATFORM_GET_CLIPBOARD(name) string name(memory_arena *Arena) +#define PLATFORM_GET_CLIPBOARD(name) string name(arena *Arena) typedef PLATFORM_RESERVE(platform_reserve); typedef PLATFORM_RELEASE(platform_release); typedef PLATFORM_COMMIT(platform_commit); typedef PLATFORM_DECOMMIT(platform_decommit); +typedef PLATFORM_ALLOCATE(platform_allocate); +typedef PLATFORM_DEALLOCATE(platform_deallocate); typedef PLATFORM_OPEN_FILE(platform_open_file); typedef PLATFORM_CLOSE_FILE(platform_close_file); typedef PLATFORM_READ_FILE(platform_read_file); @@ -40,6 +44,8 @@ platform_reserve *Reserve; platform_release *Release; platform_commit *Commit; platform_decommit *Decommit; +platform_allocate *Allocate; +platform_deallocate *Deallocate; platform_open_file *OpenFile; platform_close_file *CloseFile; platform_read_file *ReadFile; @@ -60,6 +66,8 @@ Platform.Reserve = PlatformName##_Reserve;\ Platform.Release = PlatformName##_Release;\ Platform.Commit = PlatformName##_Commit;\ Platform.Decommit = PlatformName##_Decommit;\ +Platform.Allocate = PlatformName##_Allocate;\ +Platform.Deallocate = PlatformName##_Deallocate;\ Platform.OpenFile = PlatformName##_OpenFile;\ Platform.CloseFile = PlatformName##_CloseFile;\ Platform.ReadFile = PlatformName##_ReadFile;\ diff --git a/code/opengl_render.cpp b/code/opengl_render.cpp index e0da6f3..e619981 100644 --- a/code/opengl_render.cpp +++ b/code/opengl_render.cpp @@ -106,7 +106,7 @@ static RENDER_ALLOCATE_TEXTURE(OpenGL_AllocateTexture) if(GenerateMipmap) { glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else diff --git a/code/third_party/stb_sprintf.h b/code/third_party/stb_sprintf.h index 7b9ae00..ab5df47 100644 --- a/code/third_party/stb_sprintf.h +++ b/code/third_party/stb_sprintf.h @@ -308,6 +308,12 @@ static void stbsp__lead_sign(stbsp__uint32 fl, char *sign) static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uint32 limit) { +#if VN_ASAN_ENABLED && _WIN32 + // sixten(NOTE): MSVC has no way of handling functions that disable ASAN, thus we need alternatives: + stbsp__uint32 l = 0; + while(limit-- && *s++) l++; + return l; +#else char const * sn = s; // get up to 4-byte alignment @@ -344,6 +350,7 @@ static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uin } return (stbsp__uint32)(sn - s); +#endif } STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va) diff --git a/code/vn.cpp b/code/vn.cpp index 80ca6d5..ffa9cb8 100644 --- a/code/vn.cpp +++ b/code/vn.cpp @@ -16,19 +16,25 @@ struct debug_settings global debug_settings *DEBUG_DebugSettings = 0; #endif +#include "generated/vn_character.meta.h" + #include "vn_tokenizer.h" #include "vn_config.h" #include "vn_font.h" #include "vn_text_op.h" #include "vn_ui.h" #include "vn_ui_utils.h" -#include "vn_character.h" #include "vn_scene.h" #include "vn_scene_view.h" -#include "vn_workspace.h" #include "vn_animation_curve.h" #include "vn_theme_dark.h" +#if VN_INTERNAL +#include "vn_workspace.h" +#endif + +#include "generated/vn_character.meta.c" + #include "vn_tokenizer.cpp" #include "vn_config.cpp" #include "vn_render.cpp" @@ -38,29 +44,30 @@ global debug_settings *DEBUG_DebugSettings = 0; #include "vn_animation_curve.cpp" #include "vn_scene.cpp" #include "vn_scene_view.cpp" + +#if VN_INTERNAL #include "vn_workspace.cpp" -#include "vn_character.cpp" +#endif struct vn_state { - memory_arena *Arena; - memory_arena *FrameArena; + arena *Arena; + arena *FrameArena; glyph_atlas *GlyphAtlas; config *Config; ui UI; - workspace Workspace; animation_curve_state AnimationCurveState; b32 EditorMode; - character_registry CharacterRegistry; render_handle BackgroundTexture; scene_view SceneView; #if VN_INTERNAL + workspace Workspace; debug_settings DebugSettings; #endif }; @@ -109,16 +116,16 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) //- sixten: initialize application state if(!Memory->State) { - memory_arena *Arena = ArenaAllocate(Gigabytes(1)); + arena *Arena = ArenaAlloc(Kilobytes(24), true); State = Memory->State = PushStruct(Arena, vn_state); State->Arena = Arena; - State->FrameArena = ArenaAllocate(Gigabytes(1)); + State->FrameArena = ArenaAlloc(Megabytes(1), true); State->GlyphAtlas = CreateGlyphAtlas(RenderCommands); State->Config = CreateConfig(); //- sixten: load assets - State->BackgroundTexture = CreateTextureFromPath(RenderCommands, StrLit("data/backgrounds/test.png")); + State->BackgroundTexture = CreateTextureFromPath(RenderCommands, StrLit("data/backgrounds/ddlc-club.png")); //- sixten: setup config binds and load current config { @@ -139,20 +146,23 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) SV_Init(SceneView, State->Arena); temporary_memory Scratch = GetScratch(); - string SceneInput = Platform_ReadEntireFile(Scratch.Arena, StrLit("data/character.vns")); + string SceneInput = Platform_ReadEntireFile(Scratch.Arena, StrLit("data/scene.vns")); compiled_scene Scene = S_ScriptFromText(Scratch.Arena, SceneInput); SV_SetCurrentSource(&Scene); ReleaseScratch(Scratch); SceneView->TestHappy = CreateTextureFromPath(RenderCommands, StrLit("data/characters/test_happy.png")); SceneView->TestNormal = CreateTextureFromPath(RenderCommands, StrLit("data/characters/test_normal.png")); + SceneView->MonikaLeaning = CreateTextureFromPath(RenderCommands, StrLit("data/characters/monika_leaning.png")); + SceneView->BackgroundTexture = State->BackgroundTexture; - CR_Init(&State->CharacterRegistry); UI_Init(&State->UI); - W_Init(&State->Workspace); AC_Init(&State->AnimationCurveState); +#if VN_INTERNAL + W_Init(&State->Workspace); +#endif return; } @@ -175,14 +185,18 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) //- sixten: build the ui UI_BeginBuild(RenderCommands->RenderDim); { +#if VN_INTERNAL if(State->EditorMode) { W_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); } else { +#endif SV_BuildSceneView(Input); +#if VN_INTERNAL } +#endif } UI_EndBuild(); @@ -211,6 +225,7 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) UI_RenderFrame(&Group, State->GlyphAtlas); +#if VN_INTERNAL if(DEBUG_DebugSettings->ListHotAndActive) { PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 20), 15, Color_Grey, @@ -218,5 +233,7 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 40), 15, Color_Grey, PushFormat(State->UI.FrameArena, "Active: %S:%llu", UI_BoxStringFromKey(UI_ActiveKey()), UI_ActiveKey())); } +#endif + } } \ No newline at end of file diff --git a/code/vn_animation_curve.cpp b/code/vn_animation_curve.cpp index 93de928..aa79ede 100644 --- a/code/vn_animation_curve.cpp +++ b/code/vn_animation_curve.cpp @@ -15,7 +15,7 @@ inline void AC_SetState(animation_curve_state *State) static void AC_Init(animation_curve_state *State) { - State->Arena = ArenaAllocate(Gigabytes(1)); + State->Arena = ArenaAlloc(Kilobytes(32), true); } inline animation_curve_key AC_GenerateKeyFromString(string String) diff --git a/code/vn_animation_curve.h b/code/vn_animation_curve.h index 77c329d..3c65bfe 100644 --- a/code/vn_animation_curve.h +++ b/code/vn_animation_curve.h @@ -30,7 +30,7 @@ struct animation_curve_bucket struct animation_curve_state { - memory_arena *Arena; + arena *Arena; u32 CurrentFrame; r32 dtForFrame; diff --git a/code/vn_character.cpp b/code/vn_character.cpp deleted file mode 100644 index c3bd2b0..0000000 --- a/code/vn_character.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "generated/vn_character.meta.c" - -global character_registry *Global_CharacterRegistry = 0; - -//////////////////////////////// -//~ sixten: Character String Chunk Functions -static character_string_list CR_CharacterStringListAlloc(character_registry *Registry, string String) -{ - character_string_list Result = {}; - s64 ChunksNeeded = (String.Count + CHARACTER_STRING_CHUNK_DATA_SIZE - 1) / CHARACTER_STRING_CHUNK_DATA_SIZE; - s64 BytesLeft = String.Count; - u64 StringIndex = 0; - for(s64 ChunkIndex = 0; ChunkIndex < ChunksNeeded; ChunkIndex += 1) - { - character_string_chunk *Chunk = Registry->FirstFreeChunk; - if(Chunk) - { - Registry->FirstFreeChunk = Chunk->Next; - } - else - { - Chunk = PushStructNoClear(Registry->StringArena, character_string_chunk); - } - u64 ToCopy = Min(BytesLeft, CHARACTER_STRING_CHUNK_DATA_SIZE); - Copy(Chunk->Data, String.Data+StringIndex, ToCopy); - QueuePush(Result.First, Result.Last, Chunk); - Result.ChunkCount += 1; - Result.StringCount += ToCopy; - BytesLeft -= ToCopy; - StringIndex += ToCopy; - } - return(Result); -} - -static character_string_list CR_CharacterStringListRelease(character_registry *Registry, character_string_list *List) -{ - for(character_string_chunk *Chunk = List->First, *Next = 0; Chunk != 0; Chunk = Next) - { - Next = Chunk->Next; - Chunk->Next = Registry->FirstFreeChunk; - Registry->FirstFreeChunk = Chunk; - } - ZeroStruct(List); -} - -static string CR_StringFromList(memory_arena *Arena, character_string_list *List) -{ - string Result; - Result.Count = List->StringCount; - Result.Data = PushArrayNoClear(Arena, u8, Result.Count); - s64 StringIndex = 0; - s64 BytesLeft = List->StringCount; - for(character_string_chunk *Chunk = List->First; Chunk != 0; Chunk = Chunk->Next) - { - s64 ToCopy = Min(BytesLeft, CHARACTER_STRING_CHUNK_DATA_SIZE); - Copy(Result.Data+StringIndex, Chunk->Data, ToCopy); - StringIndex += ToCopy; - BytesLeft -= ToCopy; - } - return(Result); -} - -//////////////////////////////// -//~ sixten: Character Registry Functions -static void CR_SetState(character_registry *State) -{ - Global_CharacterRegistry = State; -} - -static character_registry *CR_GetState(void) -{ - return(Global_CharacterRegistry); -} - -static character_list CR_GetCharacters(void) -{ - return(CR_GetState()->Characters); -} - -static void CR_Init(character_registry *State) -{ - CR_SetState(State); - - State->Arena = ArenaAllocate(Megabytes(32)); -} - -static character_entry *CR_EntryFromName(string Name) -{ - character_entry *Entry = 0; - - character_registry *Registry = CR_GetState(); - for(character_entry *Iter = Registry->Characters.First; Iter != 0; Iter = Iter->Next) - { - if(AreEqual(Name, Iter->Name)) - { - Entry = Iter; - break; - } - } - - if(!Entry) - { - Entry = PushStruct(Registry->Arena, character_entry); - Entry->Name = PushString(Registry->Arena, Name); - DLLInsertLast(Registry->Characters.First, Registry->Characters.Last, Entry); - } - - return(Entry); -} \ No newline at end of file diff --git a/code/vn_character.h b/code/vn_character.h deleted file mode 100644 index a3f3856..0000000 --- a/code/vn_character.h +++ /dev/null @@ -1,71 +0,0 @@ -/* date = August 30th 2023 6:28 pm */ - -#ifndef VN_CHARACTER_H -#define VN_CHARACTER_H - -#include "generated/vn_character.meta.h" - -//////////////////////////////// -//~ sixten: Character String Chunk Types -#define CHARACTER_STRING_CHUNK_DATA_SIZE (64 - sizeof(character_string_chunk *)) -struct character_string_chunk -{ - character_string_chunk *Next; - u8 Data[CHARACTER_STRING_CHUNK_DATA_SIZE]; -}; -CTAssert(sizeof(character_string_chunk) == 64); - -struct character_string_list -{ - character_string_chunk *First; - character_string_chunk *Last; - u64 ChunkCount; - s64 StringCount; -}; - -//////////////////////////////// -//~ sixten: Character Registry Types -struct character_entry -{ - character_entry *Next; - character_entry *Prev; - - string Name; -}; - -struct character_list -{ - character_entry *First; - character_entry *Last; - s64 Count; -}; - -struct character_registry -{ - memory_arena *Arena; - character_list Characters; - - memory_arena *StringArena; - character_string_chunk *FirstFreeChunk; -}; - -//////////////////////////////// -//~ sixten: Character String Chunk Functions -static character_string_list CR_CharacterStringListAlloc(character_registry *Registry, string String); -static character_string_list CR_CharacterStringListRelease(character_registry *Registry, character_string_list *List); -static string CR_StringFromList(memory_arena *Arena, character_string_list *List); - -//////////////////////////////// -//~ sixten: Character Registry Functions -static void CR_SetState(character_registry *State); -static character_registry *CR_GetState(void); -static character_list CR_GetCharacters(void); -static void CR_Init(void); -static character_entry *CR_EntryFromName(string Name); - -//////////////////////////////// -//~ sixten: Misc. Character Functions -static character_state CR_CharacterStateFromString(string Input); -static string CR_StringFromCharacterState(character_state State); - -#endif //VN_CHARACTER_H diff --git a/code/vn_character.md b/code/vn_character.md index 390e31e..6b67791 100644 --- a/code/vn_character.md +++ b/code/vn_character.md @@ -3,6 +3,7 @@ { "none", None }, { "normal", Normal }, { "happy", Happy }, + { "leaning", Leaning }, } @table_gen diff --git a/code/vn_config.cpp b/code/vn_config.cpp index be782e4..2fe553e 100644 --- a/code/vn_config.cpp +++ b/code/vn_config.cpp @@ -1,6 +1,6 @@ static config *CreateConfig(void) { - memory_arena *Arena = ArenaAllocate(Gigabytes(1)); + arena *Arena = ArenaAlloc(Kilobytes(4), true); config *Config = PushStruct(Arena, config); Config->Arena = Arena; return(Config); @@ -74,7 +74,7 @@ inline void Config_BindB32(config *Config, string Name, b32 *Target, b32 Default Config_BindEntry(Config, Name, Config_Entry_B32, Target); } -static void Config_ParseError(string Message, string FileText, s64 Offset, memory_arena *Arena) +static void Config_ParseError(string Message, string FileText, s64 Offset, arena *Arena) { text_point Point = TextPointFromOffset(FileText, Offset); string String = PushFormat(Arena, "Config: At %i:%i - %S", Point.Line, Point.Column, Message); @@ -211,7 +211,7 @@ static void Config_ReadFile(config *Config, string Path) //////////////////////////////// //~ sixten: Config Parse Type Functions -static void Config_ParseListPush(memory_arena *Arena, config_parse_list *List, string Name) +static void Config_ParseListPush(arena *Arena, config_parse_list *List, string Name) { config_parse_node *Node = PushStruct(Arena, config_parse_node); Node->Name = Name; @@ -229,7 +229,7 @@ static void Config_ParseListPop(config_parse_list *List) } } -static string Config_ParseListJoin(memory_arena *Arena, config_parse_list *List) +static string Config_ParseListJoin(arena *Arena, config_parse_list *List) { s64 TotalCount = List->TotalCountPlusOne - 1; string Result = MakeString(PushArray(Arena, u8, List->TotalCountPlusOne), TotalCount); diff --git a/code/vn_config.h b/code/vn_config.h index 97bc7fa..fd74e5f 100644 --- a/code/vn_config.h +++ b/code/vn_config.h @@ -32,7 +32,7 @@ struct config_entry_bucket struct config { - memory_arena *Arena; + arena *Arena; config_entry_bucket EntryBuckets[32]; // sixten(NOTE): Keeps track of the order in which the entries were declared. (Used during saving) @@ -81,8 +81,8 @@ static void Config_WriteFile(config *Config); //////////////////////////////// //~ sixten: Config Parse Type Functions -static void Config_ParseListPush(memory_arena *Arena, config_parse_list *List, string Name); +static void Config_ParseListPush(arena *Arena, config_parse_list *List, string Name); static void Config_ParseListPop(config_parse_list *List); -static string Config_ParseListJoin(memory_arena *Arena, config_parse_list *List); +static string Config_ParseListJoin(arena *Arena, config_parse_list *List); #endif //VN_CONFIG_H diff --git a/code/vn_font.cpp b/code/vn_font.cpp index e72e2eb..b73ffab 100644 --- a/code/vn_font.cpp +++ b/code/vn_font.cpp @@ -104,7 +104,7 @@ static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands, s32 BitmapSize = DEFAULT_GLYPH_ATLAS_DIM, s32 GlyphSize = MAX_GLYPH_SIZE) { - memory_arena *Arena = ArenaAllocate(Megabytes(128)); + arena *Arena = ArenaAlloc(Megabytes(1), true); glyph_atlas *Atlas = PushStruct(Arena, glyph_atlas); Atlas->Arena = Arena; @@ -117,14 +117,12 @@ static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands, Atlas->RenderCommands = RenderCommands; Atlas->Texture = RenderCommands->AllocateTexture(V2S32(BitmapSize, BitmapSize), Render_TextureFormat_R8, false, 0); - Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/Roboto-Regular.ttf")); - Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/Roboto-Bold.ttf")); - Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/DejaVuSansMono.ttf")); - Atlas->Fonts[Font_MonospaceOblique].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/DejaVuSansMono-Oblique.ttf")); - Atlas->Fonts[Font_Hand].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/PatrickHand-Regular.ttf")); - Atlas->Fonts[Font_Fancy].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/Merriweather-Regular.ttf")); - Atlas->Fonts[Font_Japanese].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/NotoSansJP-Regular.ttf")); - Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("fonts/icons.ttf")); + Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("data/fonts/Roboto-Regular.ttf")); + Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("data/fonts/Roboto-Bold.ttf")); + Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("data/fonts/DejaVuSansMono.ttf")); + Atlas->Fonts[Font_MonospaceOblique].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("data/fonts/DejaVuSansMono-Oblique.ttf")); + Atlas->Fonts[Font_Fancy].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("data/fonts/Merriweather-Regular.ttf")); + Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(Atlas->Arena, StrLit("data/fonts/icons.ttf")); for(s32 FontIndex = 0; FontIndex < Font_Count; diff --git a/code/vn_font.h b/code/vn_font.h index a33cd83..6a61b9b 100644 --- a/code/vn_font.h +++ b/code/vn_font.h @@ -9,9 +9,7 @@ enum font_id Font_Bold, Font_Monospace, Font_MonospaceOblique, - Font_Hand, Font_Fancy, - Font_Japanese, Font_Icons, Font_Count, @@ -110,7 +108,7 @@ struct loaded_font struct glyph_atlas { - memory_arena *Arena; + arena *Arena; s32 MaxGlyphCount; s32 GlyphsUsed; diff --git a/code/vn_platform.cpp b/code/vn_platform.cpp index 5de73df..754839b 100644 --- a/code/vn_platform.cpp +++ b/code/vn_platform.cpp @@ -50,7 +50,7 @@ inline b32 Platform_KeyRelease(platform_event_list *EventList, platform_key Key, return(Result); } -static string Platform_ReadEntireFile(memory_arena *Arena, string Path) +static string Platform_ReadEntireFile(arena *Arena, string Path) { string Result = {}; diff --git a/code/vn_platform.h b/code/vn_platform.h index 2c82261..b32fad7 100644 --- a/code/vn_platform.h +++ b/code/vn_platform.h @@ -95,6 +95,8 @@ enum platform_key Key_Backspace, Key_Delete, + Key_Escape, + Key_MouseLeft, Key_MouseMiddle, Key_MouseRight, }; diff --git a/code/vn_platform.md b/code/vn_platform.md index 1bb4cc8..fc0a324 100644 --- a/code/vn_platform.md +++ b/code/vn_platform.md @@ -4,6 +4,8 @@ { Release release RELEASE `void` `void *Pointer` } { Commit commit COMMIT `void` `void *Pointer, u64 Size` } { Decommit decommit DECOMMIT `void` `void *Pointer, u64 Size` } + { Allocate allocate ALLOCATE `void *` `u64 Size` } + { Deallocate deallocate DEALLOCATE `void` `void *Pointer` } { OpenFile open_file OPEN_FILE `platform_file_handle` `string Path, platform_access_flags FileAccess` } { CloseFile close_file CLOSE_FILE `void` `platform_file_handle Handle` } { ReadFile read_file READ_FILE `void` `platform_file_handle Handle, void *Dest, u64 Offset, u64 Size` } @@ -12,11 +14,11 @@ { SetCursor set_cursor SET_CURSOR `void` `platform_cursor Cursor` } { ToggleFullscreen toggle_fullscreen TOGGLE_FULLSCREEN `void` `void` } { ShowMessage show_message SHOW_MESSAGE `void` `string Message, platform_message_type Type` } - { BeginFileIter begin_file_iter BEGIN_FILE_ITER `platform_file_iter *` `memory_arena *Arena, string Path` } - { AdvanceFileIter advance_file_iter ADVANCE_FILE_ITER `b32` `memory_arena *Arena, platform_file_iter *Iter, platform_file_info *OutInfo` } + { BeginFileIter begin_file_iter BEGIN_FILE_ITER `platform_file_iter *` `arena *Arena, string Path` } + { AdvanceFileIter advance_file_iter ADVANCE_FILE_ITER `b32` `arena *Arena, platform_file_iter *Iter, platform_file_info *OutInfo` } { EndFileIter end_file_iter END_FILE_ITER `void` `platform_file_iter *Iter` } { SetClipboard set_clipboard SET_CLIPBOARD `void` `string String` } - { GetClipboard get_clipboard GET_CLIPBOARD `string` `memory_arena *Arena` } + { GetClipboard get_clipboard GET_CLIPBOARD `string` `arena *Arena` } } @table_gen diff --git a/code/vn_scene.cpp b/code/vn_scene.cpp index bd07985..d6eed89 100644 --- a/code/vn_scene.cpp +++ b/code/vn_scene.cpp @@ -21,11 +21,11 @@ static void S_ParseError(scene_compiler *Compiler, char *Message, s64 TokenOffse static void S_EmitByte(scene_compiler *Compiler, u8 Byte) { scene_emission_target *Target = &Compiler->TargetStack[Compiler->TargetStackIndex]; - scene_annotated_bytecode_bucket *Bucket = Target->Bucket; - scene_annotated_bytecode_chunk *Chunk = Bucket->Last; + scene_bytecode_bucket *Bucket = Target->Bucket; + scene_bytecode_chunk *Chunk = Bucket->Last; if(!Chunk || Chunk->Count >= ArrayCount(Chunk->Data) || (Target->Type == S_EmissionTarget_Named && !AreEqual(Chunk->Name, Target->Name))) { - Chunk = PushStruct(Target->Arena, scene_annotated_bytecode_chunk); + Chunk = PushStruct(Target->Arena, scene_bytecode_chunk); Chunk->Name = Target->Name; QueuePush(Bucket->First, Bucket->Last, Chunk); @@ -43,9 +43,9 @@ static void S_EmitU32(scene_compiler *Compiler, u32 Value) S_EmitByte(Compiler, Value >> 24); } -static void S_EmitBucket(scene_compiler *Compiler, scene_annotated_bytecode_bucket *Bucket) +static void S_EmitBucket(scene_compiler *Compiler, scene_bytecode_bucket *Bucket) { - for(scene_annotated_bytecode_chunk *Chunk = Bucket->First; Chunk != 0; Chunk = Chunk->Next) + for(scene_bytecode_chunk *Chunk = Bucket->First; Chunk != 0; Chunk = Chunk->Next) { for(s64 Index = 0; Index < Chunk->Count; Index += 1) { @@ -91,12 +91,12 @@ static void S_PopEmissionTarget(scene_compiler *Compiler) Compiler->TargetStackIndex -= 1; } -static scene_annotated_bytecode_chunk *S_FindBytecodeChunkByName(scene_compiler *Compiler, string Name) +static scene_bytecode_chunk *S_FindBytecodeChunkByName(scene_compiler *Compiler, string Name) { - scene_annotated_bytecode_chunk *Result = 0; + scene_bytecode_chunk *Result = 0; u64 Hash = HashString(Name); - scene_annotated_bytecode_bucket *Bucket = &Compiler->ProcBuckets[Hash%ArrayCount(Compiler->ProcBuckets)]; - for(scene_annotated_bytecode_chunk *Chunk = Bucket->First; Chunk != 0; Chunk = Chunk->Next) + scene_bytecode_bucket *Bucket = &Compiler->ProcBuckets[Hash%ArrayCount(Compiler->ProcBuckets)]; + for(scene_bytecode_chunk *Chunk = Bucket->First; Chunk != 0; Chunk = Chunk->Next) { if(AreEqual(Chunk->Name, Name)) { @@ -194,7 +194,7 @@ static void S_ParseProcedure(scene_compiler *Compiler) if(!Compiler->InPanicMode) { string Name = T_StringFromToken(Compiler->Text, NameToken); - scene_annotated_bytecode_bucket *Bucket = &Compiler->ProcBuckets[HashString(Name)%ArrayCount(Compiler->ProcBuckets)]; + scene_bytecode_bucket *Bucket = &Compiler->ProcBuckets[HashString(Name)%ArrayCount(Compiler->ProcBuckets)]; S_SetEmissionTarget(Compiler, S_NamedEmissionTarget(Compiler->Arena, Bucket, Name)); for(;Compiler->At < Compiler->TokensEnd;) @@ -468,7 +468,7 @@ static void S_ParseBranchStatement(scene_compiler *Compiler) ReleaseScratch(Scratch); } -static scene_branch_case *S_ParseBranchCase(scene_compiler *Compiler, memory_arena *Arena) +static scene_branch_case *S_ParseBranchCase(scene_compiler *Compiler, arena *Arena) { scene_branch_case *Branch = PushStruct(Arena, scene_branch_case); Branch->Name = S_ConsumeToken(Compiler, TokenKind_StringLiteral, "Expected branch label at start of branch case."); @@ -524,7 +524,7 @@ static void S_ParseNumber(scene_compiler *Compiler, b32 CanAssign) static void S_ParseString(scene_compiler *Compiler, b32 CanAssign) { - S_EmitConstant(Compiler, S_MakeSourceRef(Compiler->At[-1])); + S_EmitConstant(Compiler, S_MakeSourceRef(Pad(Compiler->At[-1].Range, -1))); } static void S_ParseGrouping(scene_compiler *Compiler, b32 CanAssign) @@ -600,19 +600,19 @@ static void S_ParsePrecedence(scene_compiler *Compiler, scene_precedence Precede struct proc_from_chunks_result { scene_proc *Proc; - scene_annotated_bytecode_chunk *NextChunk; + scene_bytecode_chunk *NextChunk; }; -static proc_from_chunks_result S_ProcFromChunks(memory_arena *Arena, scene_annotated_bytecode_chunk *First) +static proc_from_chunks_result S_ProcFromChunks(arena *Arena, scene_bytecode_chunk *First) { Assert(First != 0); string ChunkName = First->Name; //- sixten: find required bytes s64 RequiredBytes = 0; - scene_annotated_bytecode_chunk *NextChunk = 0; + scene_bytecode_chunk *NextChunk = 0; { - scene_annotated_bytecode_chunk *Chunk = First; + scene_bytecode_chunk *Chunk = First; for(;Chunk != 0 && AreEqual(Chunk->Name, ChunkName); Chunk = Chunk->Next) { RequiredBytes += Chunk->Count; @@ -627,7 +627,7 @@ static proc_from_chunks_result S_ProcFromChunks(memory_arena *Arena, scene_annot //- sixten: copy over data from chunks u8 *Dest = Proc->Data; - for(scene_annotated_bytecode_chunk *Chunk = First; Chunk != NextChunk; Chunk = Chunk->Next) + for(scene_bytecode_chunk *Chunk = First; Chunk != NextChunk; Chunk = Chunk->Next) { Copy(Dest, Chunk->Data, Chunk->Count); Dest += Chunk->Count; @@ -642,7 +642,7 @@ static proc_from_chunks_result S_ProcFromChunks(memory_arena *Arena, scene_annot return(Result); } -static compiled_scene S_ScriptFromText(memory_arena *Arena, string Text) +static compiled_scene S_ScriptFromText(arena *Arena, string Text) { compiled_scene Result = {}; @@ -679,11 +679,18 @@ static compiled_scene S_ScriptFromText(memory_arena *Arena, string Text) } } + //- sixten: bake global scope + if(Compiler.GlobalScope.First) + { + proc_from_chunks_result ProcResult = S_ProcFromChunks(Arena, Compiler.GlobalScope.First); + Result.GlobalScope = ProcResult.Proc; + } + //- sixten: bake compiled chunks for(s64 BucketIndex = 0; BucketIndex < ArrayCount(Compiler.ProcBuckets); BucketIndex += 1) { - scene_annotated_bytecode_bucket *Bucket = &Compiler.ProcBuckets[BucketIndex]; - for(scene_annotated_bytecode_chunk *Chunk = Bucket->First; Chunk != 0;) + scene_bytecode_bucket *Bucket = &Compiler.ProcBuckets[BucketIndex]; + for(scene_bytecode_chunk *Chunk = Bucket->First; Chunk != 0;) { proc_from_chunks_result ProcResult = S_ProcFromChunks(Arena, Chunk); s64 Hash = HashString(Chunk->Name); @@ -725,12 +732,22 @@ static compiled_scene S_ScriptFromText(memory_arena *Arena, string Text) return(Result); } -static compiled_scene S_CopyCompiledScene(memory_arena *Arena, compiled_scene *Compiled) +static compiled_scene S_CopyCompiledScene(arena *Arena, compiled_scene *Compiled) { compiled_scene Result = {}; Assert(Compiled->Errors.Count == 0); + //- sixten: copy the global scope + if(Compiled->GlobalScope) + { + Result.GlobalScope = PushStruct(Arena, scene_proc); + Result.GlobalScope->Name = PushString(Arena, Compiled->GlobalScope->Name); + Result.GlobalScope->Data = PushArray(Arena, u8, Compiled->GlobalScope->Count); + Copy(Result.GlobalScope->Data, Compiled->GlobalScope->Data, Compiled->GlobalScope->Count); + Result.GlobalScope->Count = Compiled->GlobalScope->Count; + } + //- sixten: copy the procs for(s64 BucketIndex = 0; BucketIndex < ArrayCount(Compiled->Buckets); BucketIndex += 1) { @@ -766,7 +783,8 @@ static void S_RuntimeError(scene_runtime *Runtime, string Message) { scene_runtime_error *Error = PushStruct(Runtime->ErrorArena, scene_runtime_error); Error->Message = PushString(Runtime->ErrorArena, Message); - DLLInsertLast(Runtime->FirstError, Runtime->LastError, Error); + DLLInsertLast(Runtime->Errors.First, Runtime->Errors.Last, Error); + Runtime->Errors.Count += 1; } static void S_RuntimeErrorF(scene_runtime *Runtime, char *Format, ...) @@ -776,11 +794,53 @@ static void S_RuntimeErrorF(scene_runtime *Runtime, char *Format, ...) scene_runtime_error *Error = PushStruct(Runtime->ErrorArena, scene_runtime_error); Error->Message = PushFormatVariadic(Runtime->ErrorArena, Format, Arguments); - DLLInsertLast(Runtime->FirstError, Runtime->LastError, Error); + DLLInsertLast(Runtime->Errors.First, Runtime->Errors.Last, Error); + Runtime->Errors.Count += 1; va_end(Arguments); } +static scene_named_value *S_FindGlobalVariableByName(scene_runtime *Runtime, string Name, b32 AlwaysCreate) +{ + scene_named_value *Result = 0; + + u64 Hash = HashString(Name); + scene_named_value_bucket *Bucket = &Runtime->GlobalVariableBuckets[Hash%ArrayCount(Runtime->GlobalVariableBuckets)]; + + //- sixten: search for the value in the bucket + for(scene_named_value_node *Node = Bucket->First; Node != 0; Node = Node->Next) + { + scene_named_value *Value = &Node->NamedValue; + if(AreEqual(Name, Value->Name)) + { + Result = Value; + break; + } + } + + //- sixten: create it if it doesn't exist + if(Result == 0) + { + //- sixten: check the free list first + scene_named_value_bucket *FreeList = &Runtime->GlobalVariableFreeList; + scene_named_value_node *Node = FreeList->First; + if(Node) + { + DLLRemove(FreeList->First, FreeList->Last, Node); + } + else + { + Node = PushStruct(Runtime->RuntimeArena, scene_named_value_node); + } + DLLInsertLast(Bucket->First, Bucket->Last, Node); + + Result = &Node->NamedValue; + Result->Name = Name; + } + + return(Result); +} + static scene_proc *S_FindProcByName(compiled_scene *Compiled, string Name) { scene_proc *Result = 0; @@ -843,6 +903,10 @@ static void S_ResetRuntime(scene_runtime *Runtime) Runtime->IP = 0; Runtime->CurrentProc = 0; Runtime->BranchCount = 0; + Fill(Runtime->GlobalVariableBuckets, 0, sizeof(Runtime->GlobalVariableBuckets)); + ZeroStruct(&Runtime->GlobalVariableFreeList); + + ZeroStruct(&Runtime->Errors); if(Runtime->RuntimeArena) { @@ -850,11 +914,11 @@ static void S_ResetRuntime(scene_runtime *Runtime) } else { - Runtime->RuntimeArena = ArenaAllocate(Megabytes(32)); + Runtime->RuntimeArena = ArenaAlloc(Kilobytes(16)); } } -static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameArena, b32 AdvanceOnAwait) +static scene_runtime_result S_Run(scene_runtime *Runtime, arena *FrameArena, b32 AdvanceOnAwait) { scene_runtime_result Result = {}; compiled_scene *Compiled = &Runtime->Compiled; @@ -862,12 +926,6 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre Assert(Runtime != 0); Assert(Compiled->IsValid); - //- sixten: default to the main proc - if(Runtime->CurrentProc == 0) - { - Runtime->CurrentProc = S_FindProcByName(Compiled, StrLit("main")); - } - // sixten(NOTE): This will only work on little endian architectures. #define S_ReadU32() (Runtime->IP += 4, *(u32 *)(Data+Runtime->IP-4)) #define S_ReadValue() Compiled->Values[S_ReadU32()] @@ -951,6 +1009,32 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre S_RuntimeError(Runtime, StrLit("This operation is not supported.")); } break; + case S_Op_DefineGlobal: + { + Runtime->IP += 1; + scene_value Value = Runtime->Compiled.Values[S_ReadU32()]; + if(Value.Kind == S_ValueKind_SourceRef) + { + string Name = Substring(Runtime->Compiled.Source, Value.SourceRef); + scene_named_value *NamedValue = S_FindGlobalVariableByName(Runtime, Name); + if(!NamedValue->Initialized) + { + NamedValue->Initialized = true; + scene_value TargetValue = S_PopStackAndImplicitConvert(Runtime); + NamedValue->Value = TargetValue; + } + else + { + S_RuntimeErrorF(Runtime, "Global %S is already defined.", Name); + } + } + else + { + S_RuntimeError(Runtime, StrLit("Incorrect value kind when retrieving global name.")); + } + + } break; + case S_Op_Jump: { Runtime->IP += 1; @@ -999,7 +1083,7 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre if(Offset.Kind == S_ValueKind_Offset) { branch_case *Branch = &Runtime->Branches[Runtime->BranchCount]; - Branch->Name = Substring(Compiled->Source, Pad(BranchName.SourceRef, -1)); + Branch->Name = Substring(Compiled->Source, BranchName.SourceRef); Branch->Offset = Offset.Offset; Runtime->BranchCount += 1; } @@ -1027,8 +1111,8 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre case S_Op_ClearDialog: { - textbox_action *Action = PushStructNoClear(FrameArena, textbox_action); - Action->Kind = TextboxActionKind_Set; + scene_textbox_action *Action = PushStructNoClear(FrameArena, scene_textbox_action); + Action->Kind = S_TextboxActionKind_Set; Action->String = StrLit(""); QueuePush(Runtime->FirstTextboxAction, Runtime->LastTextboxAction, Action); @@ -1069,15 +1153,15 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre case S_Op_LineEntry: { - textbox_action *Action = PushStructNoClear(FrameArena, textbox_action); - Action->Kind = TextboxActionKind_Append; + scene_textbox_action *Action = PushStructNoClear(FrameArena, scene_textbox_action); + Action->Kind = S_TextboxActionKind_Append; Runtime->IP += 1; scene_value Value = S_PopStack(Runtime); if(Value.Kind == S_ValueKind_SourceRef) { - Action->String = Substring(Compiled->Source, Pad(Value.SourceRef, -1)); + Action->String = Substring(Compiled->Source, Value.SourceRef); QueuePush(Runtime->FirstTextboxAction, Runtime->LastTextboxAction, Action); } else @@ -1095,7 +1179,8 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre } else { - S_RuntimeErrorF(Runtime, "Reached end of proc."); + Result.ReachedAwait = true; + Runtime->CurrentProc = 0; } } else @@ -1103,7 +1188,7 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre S_RuntimeErrorF(Runtime, "No main entry was found"); } - Result.HadError = !DLLIsEmpty(Runtime->FirstError); + Result.HadError = !DLLIsEmpty(Runtime->Errors.First); Runtime->LastResult = Result; return(Result); diff --git a/code/vn_scene.h b/code/vn_scene.h index 6786b02..7466eca 100644 --- a/code/vn_scene.h +++ b/code/vn_scene.h @@ -67,22 +67,15 @@ enum scene_opcode struct scene_bytecode_chunk { scene_bytecode_chunk *Next; - s64 Count; - u8 Data[4096]; -}; - -struct scene_annotated_bytecode_chunk -{ - scene_annotated_bytecode_chunk *Next; string Name; s64 Count; u8 Data[4096]; }; -struct scene_annotated_bytecode_bucket +struct scene_bytecode_bucket { - scene_annotated_bytecode_chunk *First; - scene_annotated_bytecode_chunk *Last; + scene_bytecode_chunk *First; + scene_bytecode_chunk *Last; s64 Count; }; @@ -150,8 +143,8 @@ enum scene_emission_target_type struct scene_emission_target { - memory_arena *Arena; - scene_annotated_bytecode_bucket *Bucket; + arena *Arena; + scene_bytecode_bucket *Bucket; scene_emission_target_type Type; string Name; }; @@ -160,7 +153,7 @@ struct scene_branch_case { scene_branch_case *Next; token Name; - scene_annotated_bytecode_bucket Bucket; + scene_bytecode_bucket Bucket; scene_value *OffsetValue; scene_value *EndOffsetValue; }; @@ -176,7 +169,7 @@ struct scene_character_action struct scene_compiler { - memory_arena *Arena; + arena *Arena; b32 InPanicMode; b32 EncounteredError; @@ -187,8 +180,8 @@ struct scene_compiler token *TokensEnd; token *At; - scene_annotated_bytecode_bucket GlobalScope; - scene_annotated_bytecode_bucket ProcBuckets[32]; + scene_bytecode_bucket GlobalScope; + scene_bytecode_bucket ProcBuckets[32]; scene_emission_target TargetStack[16]; s32 TargetStackIndex; @@ -219,6 +212,7 @@ struct scene_proc_bucket struct compiled_scene { + scene_proc *GlobalScope; scene_proc_bucket Buckets[16]; scene_value *Values; s64 ValueCount; @@ -236,22 +230,50 @@ struct scene_runtime_error string Message; }; +struct scene_runtime_error_list +{ + scene_runtime_error *First; + scene_runtime_error *Last; + s64 Count; +}; + +struct scene_named_value +{ + b32 Initialized; + string Name; + scene_value Value; +}; + +struct scene_named_value_node +{ + scene_named_value_node *Next; + scene_named_value_node *Prev; + scene_named_value NamedValue; +}; + +struct scene_named_value_bucket +{ + s64 Count; + scene_named_value_node *First; + scene_named_value_node *Last; +}; + struct scene_runtime_result { b32 HadError; b32 ReachedAwait; }; -enum textbox_action_kind +enum scene_textbox_action_kind { - TextboxActionKind_Set, - TextboxActionKind_Append, + S_TextboxActionKind_Set, + S_TextboxActionKind_Append, }; -struct textbox_action +struct scene_textbox_action { - textbox_action *Next; - textbox_action_kind Kind; + scene_textbox_action *Next; + scene_textbox_action_kind Kind; string String; }; @@ -272,27 +294,27 @@ struct scene_runtime compiled_scene Compiled; // sixten: runtime state - memory_arena *RuntimeArena; + arena *RuntimeArena; scene_proc *CurrentProc; s64 IP; scene_runtime_stack Stack; + scene_named_value_bucket GlobalVariableBuckets[16]; + scene_named_value_bucket GlobalVariableFreeList; // sixten: errors - memory_arena *ErrorArena; - scene_runtime_error *FirstError; - scene_runtime_error *LastError; + arena *ErrorArena; + scene_runtime_error_list Errors; // sixten: branches branch_case Branches[16]; s64 BranchCount; // sixten: result - textbox_action *FirstTextboxAction; - textbox_action *LastTextboxAction; + scene_runtime_result LastResult; + scene_textbox_action *FirstTextboxAction; + scene_textbox_action *LastTextboxAction; scene_character_action *FirstCharacterAction; scene_character_action *LastCharacterAction; - branch_case *FirstBranchCase; - scene_runtime_result LastResult; }; //////////////////////////////// @@ -338,6 +360,14 @@ inline scene_value S_MakeSourceRef(token Token) return(Result); } +inline scene_value S_MakeSourceRef(range1_s64 Range) +{ + scene_value Result; + Result.Kind = S_ValueKind_SourceRef; + Result.SourceRef = Range; + return(Result); +} + inline scene_value S_MakeOffset(s64 Offset) { scene_value Result; @@ -352,15 +382,15 @@ static void S_ParseError(scene_compiler *Compiler, char *Message, s64 TokenOffse //- sixten: bytecode helpers static void S_EmitByte(scene_compiler *Compiler, u8 Byte); static void S_EmitU32(scene_compiler *Compiler, u32 Value); -static void S_EmitBucket(scene_compiler *Compiler, scene_annotated_bytecode_bucket *Bucket); +static void S_EmitBucket(scene_compiler *Compiler, scene_bytecode_bucket *Bucket); static u64 S_MakeConstant(scene_compiler *Compiler, scene_value Value); static void S_EmitConstant(scene_compiler *Compiler, scene_value Value); static void S_SetEmissionTarget(scene_compiler *Compiler, scene_emission_target Target); static void S_PushEmissionTarget(scene_compiler *Compiler, scene_emission_target Target); static void S_PopEmissionTarget(scene_compiler *Compiler); -static scene_annotated_bytecode_chunk *S_FindBytecodeChunkByName(scene_compiler *Compiler, string Name); +static scene_bytecode_chunk *S_FindBytecodeChunkByName(scene_compiler *Compiler, string Name); -inline scene_emission_target S_RawEmissionTarget(memory_arena *Arena, scene_annotated_bytecode_bucket *Bucket) +inline scene_emission_target S_RawEmissionTarget(arena *Arena, scene_bytecode_bucket *Bucket) { scene_emission_target Target = {}; Target.Arena = Arena; @@ -369,7 +399,7 @@ inline scene_emission_target S_RawEmissionTarget(memory_arena *Arena, scene_anno return(Target); } -inline scene_emission_target S_NamedEmissionTarget(memory_arena *Arena, scene_annotated_bytecode_bucket *Bucket, string Name) +inline scene_emission_target S_NamedEmissionTarget(arena *Arena, scene_bytecode_bucket *Bucket, string Name) { scene_emission_target Target = {}; Target.Arena = Arena; @@ -395,7 +425,7 @@ static void S_ParseNamedVariable(scene_compiler *Compiler, token Token, b32 CanA static void S_ParseLineEntry(scene_compiler *Compiler); static void S_ParseJumpStatement(scene_compiler *Compiler); static void S_ParseBranchStatement(scene_compiler *Compiler); -static scene_branch_case *S_ParseBranchCase(scene_compiler *Compiler, memory_arena *Arena); +static scene_branch_case *S_ParseBranchCase(scene_compiler *Compiler, arena *Arena); static void S_ParseStatement(scene_compiler *Compiler); static void S_ParseExpression(scene_compiler *Compiler); static void S_ParseLiteral(scene_compiler *Compiler, b32 CanAssign); @@ -407,16 +437,17 @@ static void S_ParseBinary(scene_compiler *Compiler, b32 CanAssign); static void S_ParsePrecedence(scene_compiler *Compiler, scene_precedence Precedence); //- sixten: debugging -static string S_DisassembleBytecode(scene_compiler *Compiler, scene_annotated_bytecode_chunk *Chunk, memory_arena *Arena); +static string S_DisassembleBytecode(scene_compiler *Compiler, scene_bytecode_chunk *Chunk, arena *Arena); //- sixten: compilation -static compiled_scene S_ScriptFromText(memory_arena *Arena, string Text); -static compiled_scene S_CopyCompiledScene(memory_arena *Arena, compiled_scene *Compiled); +static compiled_scene S_ScriptFromText(arena *Arena, string Text); +static compiled_scene S_CopyCompiledScene(arena *Arena, compiled_scene *Compiled); //////////////////////////////// //~ sixten: Scene Runtime Functions static scene_proc *S_FindProcByName(compiled_scene *Compiled, string Name); +static scene_named_value *S_FindGlobalVariableByName(scene_runtime *Runtime, string Name, b32 AlwaysCreate = true); static void S_ResetRuntime(scene_runtime *Runtime); -static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameArena, b32 AdvanceOnAwait); +static scene_runtime_result S_Run(scene_runtime *Runtime, arena *FrameArena, b32 AdvanceOnAwait); #endif //VN_SCENE_H diff --git a/code/vn_scene_view.cpp b/code/vn_scene_view.cpp index c1510e6..8392ceb 100644 --- a/code/vn_scene_view.cpp +++ b/code/vn_scene_view.cpp @@ -1,4 +1,4 @@ -thread_local scene_view *ThreadLocal_SceneView = 0; +per_thread scene_view *ThreadLocal_SceneView = 0; static void SV_SetState(scene_view *View) { @@ -17,29 +17,73 @@ static void SV_NewFrame(scene_view *View, platform_event_list *EventList, r32 dt View->dtForFrame = dtForFrame; } -static void SV_SetCurrentSource(compiled_scene *Compiled) +static void SV_Reset(void) { scene_view *SceneView = SV_GetState(); - // sixten(TODO): extract runtime information required to seamlessly transition between compilations - - ArenaClear(SceneView->SceneArena); - SceneView->Runtime.Compiled = S_CopyCompiledScene(SceneView->SceneArena, Compiled); + ArenaClear(SceneView->Runtime.ErrorArena); S_ResetRuntime(&SceneView->Runtime); + + // sixten: reset textbox + SceneView->Textbox.String.Count = 0; + + // sixten: reset last talking character + SceneView->LastTalkingCharacter.Count = 0; + SceneView->CharacterIsTalking = false; + + SceneView->OnscreenCharacterCount = 0; } -static void SV_Init(scene_view *SceneView, memory_arena *TextboxArena) +static void SV_SetCurrentSource(compiled_scene *Compiled) +{ + scene_view *SceneView = SV_GetState(); + scene_runtime *Runtime = &SceneView->Runtime; + + // sixten(TODO): extract runtime information required to seamlessly transition between compilations + SV_Reset(); + + ArenaClear(SceneView->SceneArena); + Runtime->Compiled = S_CopyCompiledScene(SceneView->SceneArena, Compiled); + + //- sixten: run top level + Runtime->CurrentProc = Runtime->Compiled.GlobalScope; + if(Runtime->CurrentProc) + { + temporary_memory Scratch = GetScratch(0, 0); + for(;;) + { + scene_runtime_result RunResult = S_Run(Runtime, Scratch.Arena, false); + if(RunResult.ReachedAwait || RunResult.HadError) + { + break; + } + } + ReleaseScratch(Scratch); + } + + //- sixten: find main proc + Runtime->CurrentProc = S_FindProcByName(&Runtime->Compiled, StrLit("main")); + Runtime->IP = 0; +} + +static void SV_Init(scene_view *SceneView, arena *TextboxArena) { SV_SetState(SceneView); - SceneView->SceneArena = ArenaAllocate(Gigabytes(1)); - SceneView->Runtime.ErrorArena = ArenaAllocate(Megabytes(1)); - - S_ResetRuntime(&SceneView->Runtime); + SceneView->SceneArena = ArenaAlloc(Kilobytes(16), true); + SceneView->Runtime.ErrorArena = ArenaAlloc(Kilobytes(4), true); SceneView->Textbox.Capacity = 4096; SceneView->Textbox.String.Data = PushArray(TextboxArena, u8, SceneView->Textbox.Capacity); - SceneView->Textbox.String.Count = 0; + + SV_Reset(); +} + +static b32 SV_CurrentlyInProc(void) +{ + scene_view *SceneView = SV_GetState(); + b32 Result = (SceneView->Runtime.CurrentProc != 0); + return(Result); } struct text_properties @@ -52,6 +96,7 @@ struct text_properties static void RenderAnimatedText(render_group *Group, glyph_atlas *Atlas, text_properties Properties, string Text, r32 CharsToRender, v2_r32 P, r32 WrapWidth) { v2_r32 Offset = V2R32(0, 0); + v2_r32 ShadowOffset = V2R32(Properties.FontSize*0.1, Properties.FontSize*0.1); u8 *TextBegin = Text.Data; u8 *TextEnd = TextBegin+Text.Count; @@ -84,6 +129,7 @@ static void RenderAnimatedText(render_group *Group, glyph_atlas *Atlas, text_pro Offset.y += Properties.LineHeight; } + PushText(Group, Atlas, Properties.Font, P+Offset+ShadowOffset, Properties.FontSize, Color_Black, Word); Offset.x += PushText(Group, Atlas, Properties.Font, P+Offset, Properties.FontSize, Color_White, Word); if(WordEnd != TrueWordEnd) @@ -129,6 +175,8 @@ struct scene_textbox_data { textbox *Textbox; ui_box *SceneViewBox; + string Name; + r32 NameT; }; UI_CUSTOM_DRAW_CALLBACK(BuildSceneTextboxDrawCallback) @@ -136,23 +184,38 @@ UI_CUSTOM_DRAW_CALLBACK(BuildSceneTextboxDrawCallback) scene_textbox_data *TextboxData = (scene_textbox_data *)Data; textbox *Textbox = TextboxData->Textbox; + r32 GlobalScale = CalculateGlobalScaleFromRootBox(TextboxData->SceneViewBox); + //- sixten: render textbox - v4 TopColor = V4(0, 0, 0, 0.8f); - v4 BottomColor = V4(0, 0, 0, 0.5f); - range2_r32 Dest = Range2R32(Box->Rect.Min, Box->Rect.Max); - PushQuad(Group, Dest, TopColor, TopColor, BottomColor, BottomColor, 0, 0, 0); + { + v4 TopColor = V4(0, 0, 0, 0.8f); + v4 BottomColor = V4(0, 0, 0, 0.5f); + range2_r32 Dest = Pad(Range2R32(Box->Rect.Min, Box->Rect.Max), V2(GlobalScale, GlobalScale)*2.0f); + PushQuad(Group, Dest, TopColor, TopColor, BottomColor, BottomColor, 0, GlobalScale, 0); + } //- sixten: render text - string Text = Textbox->String; - r32 CharsRevealed = Textbox->CharsRevealed; - r32 GlobalScale = CalculateGlobalScaleFromRootBox(TextboxData->SceneViewBox); - text_properties Properties = {}; - Properties.Font = Font_Fancy; - Properties.FontSize = GlobalScale; - Properties.LineHeight = GlobalScale*1.5f; - r32 Padding = 1.5f*GlobalScale; - v2 Offset = V2R32(Padding, Padding); - RenderAnimatedText(Group, Atlas, Properties, Text, CharsRevealed, Box->Rect.Min+Offset, DimOfRange(Box->Rect).x-2*Padding); + { + string Text = Textbox->String; + r32 CharsRevealedT = Textbox->CharsRevealedT; + text_properties Properties = {}; + Properties.Font = Font_Fancy; + Properties.FontSize = GlobalScale; + Properties.LineHeight = GlobalScale*1.5f; + r32 Padding = 1.5f*GlobalScale; + v2 Offset = V2R32(Padding, Padding); + RenderAnimatedText(Group, Atlas, Properties, Text, CharsRevealedT, Box->Rect.Min+Offset, DimOfRange(Box->Rect).x-2*Padding); + } + + //- sixten: render character name + { + string Name = TextboxData->Name; + r32 T = TextboxData->NameT; + v2 TextP = Box->Rect.Min + V2(1.5f*GlobalScale, -GlobalScale*T); + PushText(Group, Atlas, Font_Fancy, TextP+V2(GlobalScale*0.1, GlobalScale*0.1), GlobalScale, SetAlpha(Color_Black, T), Name); + PushText(Group, Atlas, Font_Fancy, TextP, GlobalScale, SetAlpha(Color_White, T), Name); + } + } UI_CUSTOM_DRAW_CALLBACK(BuildSceneDrawCallback) @@ -165,22 +228,32 @@ UI_CUSTOM_DRAW_CALLBACK(BuildSceneDrawCallback) //- sixten: render background // sixten(TODO, but soon): Currently we add Box->Rect.Min to everything, but that should really be a transform // on the render group. +#if 0 + persist r32 Time = 0; + Time += 1 / 1200.0f; + r32 r = 30; + v2_r32 Offset = V2(Sin(Time)+0.5*Sin(43+2.43*Time)+Sin(424+Time*16)*0.1, Sin(8+Time)+0.5*Sin(43+2.43*Time)+Sin(4242+Time*16)*0.1)*(1.0f/1.6f)*r; + range2_r32 BackgroundDest = Range2R32(Box->Rect.Min-V2(r, r)+Offset, RenderDim+Box->Rect.Min+V2(r, r)+Offset); + range2_r32 BackgroundSource = Range2R32(V2R32(0, 0), ConvertV2ToR32(DimFromTexture(SceneView->BackgroundTexture))); + PushTexturedQuad(Group, BackgroundDest, BackgroundSource, Color_White, Color_White, Color_White, Color_White, 0, 0, 0, SceneView->BackgroundTexture); +#else range2_r32 BackgroundDest = Range2R32(Box->Rect.Min, RenderDim+Box->Rect.Min); range2_r32 BackgroundSource = Range2R32(V2R32(0, 0), ConvertV2ToR32(DimFromTexture(SceneView->BackgroundTexture))); PushTexturedQuad(Group, BackgroundDest, BackgroundSource, Color_White, Color_White, Color_White, Color_White, 0, 0, 0, SceneView->BackgroundTexture); +#endif //- sixten: render characters - for(s32 CharacterIndex = 0; CharacterIndex < SceneView->CharacterCount; CharacterIndex += 1) + for(s32 CharacterIndex = 0; CharacterIndex < SceneView->OnscreenCharacterCount; CharacterIndex += 1) { scene_view_character_data *Character = SceneView->OnscreenCharacters + CharacterIndex; v4_r32 BlendColor = LinearBlend(Color_White, Color_Black, 0.5-Character->TalkingT*0.5); BlendColor.a = Character->ActiveT; - r32 Scale = (Character->TextureScale + Character->TalkingT*0.001)*(0.95+Character->ActiveT*0.05)*GlobalScale; - render_handle CharacterHandle = Character->Texture; + r32 Scale = (Character->Info.Scale + Character->TalkingT*0.001)*(0.95+Character->ActiveT*0.05)*GlobalScale; + render_handle CharacterHandle = Character->Info.Texture; v2_r32 CharacterDim = ConvertV2ToR32(DimFromTexture(CharacterHandle)); v2_r32 CharacterOriginP = V2R32(RenderDim.x*Character->PctP, RenderDim.y); - v2_r32 CharacterMidP = V2R32(CharacterOriginP.x, CharacterOriginP.y - CharacterDim.y*Scale/2); + v2_r32 CharacterMidP = Box->Rect.Min+V2R32(CharacterOriginP.x, CharacterOriginP.y - CharacterDim.y*Scale/2); range2_r32 CharacterDest = Range2R32(CharacterMidP-CharacterDim*0.5f*Scale, CharacterMidP+CharacterDim*0.5f*Scale); range2_r32 CharacterSource = Range2R32(V2R32(0, 0), CharacterDim); PushTexturedQuad(Group, CharacterDest, CharacterSource, BlendColor, BlendColor, BlendColor, BlendColor, 0, 0, 0, CharacterHandle); @@ -197,35 +270,48 @@ static void BuildScene(scene_view *View) ui_box *Box = UI_MakeBox(0, StrLit("Scene View")); UI_EquipBoxCustomDrawCallback(Box, BuildSceneDrawCallback, View); - UI_Parent(Box) + if(SV_CurrentlyInProc()) { - UI_WidthFill UI_Height(UI_Percent(1, 0)) UI_Row() UI_FillPadding UI_Column() UI_FillPadding + UI_Parent(Box) { - b32 FoundOffset = false; - s64 Offset = 0; - for(s32 BranchIndex = 0; BranchIndex < Runtime->BranchCount; BranchIndex += 1) + //- sixten: build branches + UI_WidthFill UI_Height(UI_Percent(1, 0)) UI_Row() UI_FillPadding UI_Column() UI_FillPadding { - branch_case *Branch = &Runtime->Branches[BranchIndex]; - if(UI_ButtonF("%S#%i", Branch->Name, BranchIndex).Clicked) + b32 FoundOffset = false; + s64 Offset = 0; + for(s32 BranchIndex = 0; BranchIndex < Runtime->BranchCount; BranchIndex += 1) { - Offset = Branch->Offset; - FoundOffset = true; + branch_case *Branch = &Runtime->Branches[BranchIndex]; + if(UI_ButtonF("%S#%i", Branch->Name, BranchIndex).Clicked) + { + Offset = Branch->Offset; + FoundOffset = true; + } + } + if(FoundOffset) + { + Runtime->IP += 1+Offset; + Runtime->BranchCount = 0; } } - if(FoundOffset) + + //- sixten: build textbox + UI_Size(UI_Percent(1, 1), UI_Percent(0.3, 1)) { - Runtime->IP += 1+Offset; - Runtime->BranchCount = 0; + ui_box *TextBox = UI_MakeBox(0, StrLit("Scene Textbox")); + + scene_textbox_data *TextboxData = PushStruct(UI_FrameArena(), scene_textbox_data); + TextboxData->Textbox = Textbox; + TextboxData->SceneViewBox = Box; + TextboxData->Name = View->LastTalkingCharacter; + TextboxData->NameT = View->CharacterIsTalkingT; + UI_EquipBoxCustomDrawCallback(TextBox, BuildSceneTextboxDrawCallback, TextboxData); } } - - UI_SetNextWidth(UI_Percent(1, 1)); - UI_SetNextHeight(UI_Percent(0.3, 1)); - ui_box *TextBox = UI_MakeBox(0, StrLit("Scene Textbox")); - scene_textbox_data *TextboxData = PushStruct(UI_FrameArena(), scene_textbox_data); - TextboxData->Textbox = Textbox; - TextboxData->SceneViewBox = Box; - UI_EquipBoxCustomDrawCallback(TextBox, BuildSceneTextboxDrawCallback, TextboxData); + } + else + { + //- sixten: render environmental objects } } @@ -238,7 +324,7 @@ static void BuildErrorScreen(scene_runtime *Runtime, vn_input *Input) { UI_Font(Font_Bold) UI_Size(UI_TextContent(0, 1), UI_TextContent(0, 1)) UI_FontSize(32) UI_LabelF("A runtime error has occurred"); s64 ErrorIndex = 0; - for(scene_runtime_error *Error = Runtime->FirstError; Error != 0; Error = Error->Next, ErrorIndex += 1) + for(scene_runtime_error *Error = Runtime->Errors.First; Error != 0; Error = Error->Next, ErrorIndex += 1) { UI_Spacer(UI_Em(3, 1)); UI_SetNextCornerRadius(3); @@ -259,7 +345,7 @@ static void BuildErrorScreen(scene_runtime *Runtime, vn_input *Input) } if(IgnoreSignal.Clicked) { - Runtime->FirstError = Runtime->LastError = 0; + ZeroStruct(&Runtime->Errors); ArenaClear(Runtime->ErrorArena); } @@ -272,10 +358,7 @@ static void BuildErrorScreen(scene_runtime *Runtime, vn_input *Input) } if(RestartSignal.Clicked) { - Runtime->FirstError = Runtime->LastError = 0; - Runtime->IP = 0; - Runtime->CurrentProc = 0; - ArenaClear(Runtime->ErrorArena); + SV_Reset(); } UI_Spacer(UI_Em(1, 1)); @@ -294,7 +377,7 @@ static scene_view_character_data *SV_CharacterDataFromName(string Name) scene_view *View = SV_GetState(); - for(s32 CharacterIndex = 0; CharacterIndex < View->CharacterCount; CharacterIndex += 1) + for(s32 CharacterIndex = 0; CharacterIndex < View->OnscreenCharacterCount; CharacterIndex += 1) { scene_view_character_data *Character = View->OnscreenCharacters + CharacterIndex; if(AreEqual(Character->Name, Name)) @@ -305,24 +388,26 @@ static scene_view_character_data *SV_CharacterDataFromName(string Name) } //- sixten: create character if not initialized - if(!Result && View->CharacterCount < ArrayCount(View->OnscreenCharacters)) + if(!Result && View->OnscreenCharacterCount < ArrayCount(View->OnscreenCharacters)) { - s32 CharacterIndex = View->CharacterCount; - View->CharacterCount += 1; + s32 CharacterIndex = View->OnscreenCharacterCount; + View->OnscreenCharacterCount += 1; Result = View->OnscreenCharacters + CharacterIndex; *Result = {}; Result->Name = Name; Result->Active = true; - Result->PctP = (r32)(CharacterIndex + 1) / (View->CharacterCount + 1); + Result->PctP = (r32)(CharacterIndex + 1) / (View->OnscreenCharacterCount + 1); } return(Result); } -static render_handle SV_CharacterTextureFromAction(scene_character_action *Action) +static scene_view_character_texture_info SV_CharacterTextureFromAction(scene_character_action *Action) { - render_handle Result = EmptyRenderHandle(); + scene_view_character_texture_info Result = {}; + Result.Texture = EmptyRenderHandle(); + Result.Scale = 1.0f; scene_view *View = SV_GetState(); @@ -330,16 +415,47 @@ static render_handle SV_CharacterTextureFromAction(scene_character_action *Actio { switch(Action->State) { - case CR_State_Normal: { Result = View->TestNormal; } break; - case CR_State_Happy: { Result = View->TestHappy; } break; + case CR_State_Normal: { Result.Texture = View->TestNormal; } break; + case CR_State_Happy: { Result.Texture = View->TestHappy; } break; default: break; } + + Result.Scale = 0.017f; + } + else if(AreEqual(StrLit("monika"), Action->Target)) + { + switch(Action->State) + { + case CR_State_Leaning: { Result.Texture = View->MonikaLeaning; } break; + default: break; + } + Result.Scale = 0.033f; } - return(Result); } -static void SV_Update(memory_arena *FrameArena) +static r32 SV_CalculateTargetPctP(s32 TrueCharacterIndex) +{ + scene_view *View = SV_GetState(); + s32 CharacterCount = 0; + s32 AssumedCharacterIndex = 0; + for(s32 CharacterIndex = 0; CharacterIndex < View->OnscreenCharacterCount; CharacterIndex += 1) + { + scene_view_character_data *Data = View->OnscreenCharacters + CharacterIndex; + if(Data->Active) + { + CharacterCount += 1; + if(CharacterIndex < TrueCharacterIndex) + { + AssumedCharacterIndex += 1; + } + } + } + r32 Result = (r32)(AssumedCharacterIndex + 1) / (Max(CharacterCount, 1) + 1); + return(Result); +} + +static void SV_UpdateInDialog(arena *FrameArena) { scene_view *SceneView = SV_GetState(); textbox *Textbox = &SceneView->Textbox; @@ -348,35 +464,11 @@ static void SV_Update(memory_arena *FrameArena) r32 dtForFrame = SceneView->dtForFrame; compiled_scene *Compiled = &Runtime->Compiled; - //- sixten: update the characters - for(s32 CharacterIndex = 0; CharacterIndex < SceneView->CharacterCount; CharacterIndex += 1) - { - scene_view_character_data *Data = SceneView->OnscreenCharacters + CharacterIndex; - - AC_AnimateValueDirect(Data->Active, 0.3f, &Data->ActiveT); - AC_AnimateValueDirect(Data->Talking, 0.3f, &Data->TalkingT); - - r32 TargetPctP = (r32)(CharacterIndex+1)/(SceneView->CharacterCount+1); - AC_AnimateValueDirect(TargetPctP, 0.3f, &Data->PctP); - } - - //- sixten: prune any unactive characters - for(s32 CharacterIndex = 0; CharacterIndex < SceneView->CharacterCount; CharacterIndex += 1) - { - scene_view_character_data *Data = SceneView->OnscreenCharacters + CharacterIndex; - if(!Data->Active && Data->ActiveT < 0.01) - { - Move(Data, Data+1, SceneView->CharacterCount-CharacterIndex-1); - SceneView->CharacterCount -= 1; - CharacterIndex -= 1; - } - } - if(Compiled && Compiled->IsValid) { b32 PlayerAction = (Platform_KeyPress(EventList, Key_Space)||Platform_KeyPress(EventList, Key_MouseLeft)); - if(DLLIsEmpty(Runtime->FirstError)) + if(!Runtime->LastResult.HadError) { b32 AdvanceOnAwait = (Textbox->CharsRevealed >= Textbox->String.Count) && PlayerAction; @@ -389,7 +481,7 @@ static void SV_Update(memory_arena *FrameArena) } } } - r32 CharsPerSecond = 35.0f;//10.0f; + r32 CharsPerSecond = 25.0f; Textbox->CharsRevealed += dtForFrame*CharsPerSecond; Textbox->CharsRevealed = Min(Textbox->CharsRevealed, (r32)Textbox->String.Count); @@ -398,20 +490,23 @@ static void SV_Update(memory_arena *FrameArena) Textbox->CharsRevealed = Textbox->String.Count; } + AC_AnimateValueDirect(Textbox->CharsRevealed, 0.05f, &Textbox->CharsRevealedT); + //- sixten: apply the textbox actions - for(textbox_action *Action = Runtime->FirstTextboxAction; Action != 0; Action = Action->Next) + for(scene_textbox_action *Action = Runtime->FirstTextboxAction; Action != 0; Action = Action->Next) { - if(Action->Kind == TextboxActionKind_Set) + if(Action->Kind == S_TextboxActionKind_Set) { string ReplaceString = Action->String; Textbox->String.Count = Min(ReplaceString.Count, Textbox->Capacity); Copy(Textbox->String.Data, ReplaceString.Data, Textbox->String.Count); + Textbox->CharsRevealedT = 0; Textbox->CharsRevealed = 0; } - else if(Action->Kind == TextboxActionKind_Append) + else if(Action->Kind == S_TextboxActionKind_Append) { string Addend = Action->String; - Textbox->CharsRevealed = Textbox->String.Count; + Textbox->CharsRevealedT = Textbox->String.Count; s64 NewCount = Min(Textbox->String.Count+Addend.Count, Textbox->Capacity-1); Copy(Textbox->String.Data+Textbox->String.Count, Action->String.Data, NewCount-Textbox->String.Count); Textbox->String.Count = NewCount; @@ -423,6 +518,18 @@ static void SV_Update(memory_arena *FrameArena) } Runtime->FirstTextboxAction = Runtime->LastTextboxAction = 0; + //- sixten: make all characters non-talking + if(Runtime->FirstCharacterAction != 0) + { + for(s32 CharacterIndex = 0; CharacterIndex < SceneView->OnscreenCharacterCount; CharacterIndex += 1) + { + scene_view_character_data *Data = SceneView->OnscreenCharacters + CharacterIndex; + Data->Talking = false; + } + + SceneView->CharacterIsTalking = false; + } + //- sixten: apply character actions for(scene_character_action *Action = Runtime->FirstCharacterAction; Action != 0; Action = Action->Next) { @@ -435,9 +542,20 @@ static void SV_Update(memory_arena *FrameArena) } else { - Data->Texture = SV_CharacterTextureFromAction(Action); - Data->TextureScale = 0.017f; + Data->Info = SV_CharacterTextureFromAction(Action); Data->Talking = true; + + SceneView->CharacterIsTalking = true; + + string CharacterName = Action->Target; + scene_named_value *CharacterNameValue = S_FindGlobalVariableByName(Runtime, CharacterName, false); + if(CharacterNameValue && CharacterNameValue->Value.Kind == S_ValueKind_String) + { + CharacterName = CharacterNameValue->Value.String; + } + + SceneView->LastTalkingCharacter = MakeString(SceneView->LastTalkingCharacterBuffer, CharacterName.Count); + Copy(SceneView->LastTalkingCharacterBuffer, CharacterName.Data, CharacterName.Count); } } @@ -445,6 +563,57 @@ static void SV_Update(memory_arena *FrameArena) } } +static void SV_Update(arena *FrameArena) +{ + scene_view *SceneView = SV_GetState(); + + //- sixten: update the characters + { + AC_AnimateValueDirect(SceneView->CharacterIsTalking, 0.3f, &SceneView->CharacterIsTalkingT); + + for(s32 CharacterIndex = 0; CharacterIndex < SceneView->OnscreenCharacterCount; CharacterIndex += 1) + { + scene_view_character_data *Data = SceneView->OnscreenCharacters + CharacterIndex; + + AC_AnimateValueDirect(Data->Active, 0.5f, &Data->ActiveT); + AC_AnimateValueDirect(Data->Talking, 0.4f, &Data->TalkingT); + + r32 TargetPctP; + if(Data->Active) + { + TargetPctP = SV_CalculateTargetPctP(CharacterIndex); + } + else + { + TargetPctP = (r32)(CharacterIndex+1)/(SceneView->OnscreenCharacterCount+1); + } + AC_AnimateValueDirect(TargetPctP, 0.4f, &Data->PctP); + } + } + + //- sixten: prune any unactive characters + for(s32 CharacterIndex = 0; CharacterIndex < SceneView->OnscreenCharacterCount; CharacterIndex += 1) + { + scene_view_character_data *Data = SceneView->OnscreenCharacters + CharacterIndex; + if(!Data->Active && Data->ActiveT < 0.01) + { + Move(Data, Data+1, (SceneView->OnscreenCharacterCount-CharacterIndex-1)*sizeof(scene_view_character_data)); + SceneView->OnscreenCharacterCount -= 1; + CharacterIndex -= 1; + } + } + + //- sixten: update scene + if(SV_CurrentlyInProc()) + { + SV_UpdateInDialog(FrameArena); + } + else + { + + } +} + static void SV_BuildSceneView(vn_input *Input) { scene_view *SceneView = SV_GetState(); @@ -456,23 +625,6 @@ static void SV_BuildSceneView(vn_input *Input) else if(SceneView->Runtime.Compiled.IsValid) { BuildScene(SceneView); - -#if 0 - UI_Tooltip - { - UI_SetNextFixedP(V2R32(0, 0)); - UI_SetNextSize(UI_ChildrenSum(1, 1), UI_ChildrenSum(1, 1)); - UI_Column() UI_Size(UI_TextContent(15, 1), UI_TextContent(15, 1)) - { - UI_Row() - { - UI_LabelF("Character Count: %i", SceneView->CharacterCount); - if(UI_ButtonF("+").Clicked) ++SceneView->CharacterCount; - if(UI_ButtonF("-").Clicked) --SceneView->CharacterCount; - } - } - } -#endif } else { diff --git a/code/vn_scene_view.h b/code/vn_scene_view.h index 5b3ac59..6abe779 100644 --- a/code/vn_scene_view.h +++ b/code/vn_scene_view.h @@ -7,50 +7,71 @@ struct textbox { string String; s64 Capacity; + r32 CharsRevealedT; r32 CharsRevealed; }; +struct scene_view_character_texture_info +{ + render_handle Texture; + r32 Scale; +}; + struct scene_view_character_data { string Name; + + scene_view_character_texture_info Info; + b32 Active; - b32 Talking; - - render_handle Texture; - r32 TextureScale; - r32 ActiveT; + + b32 Talking; r32 TalkingT; + r32 PctP; }; struct scene_view { - memory_arena *SceneArena; + arena *SceneArena; - // sixten: input + //- sixten: state + scene_runtime Runtime; + textbox Textbox; + + u8 LastTalkingCharacterBuffer[32]; + string LastTalkingCharacter; + + b32 CharacterIsTalking; + r32 CharacterIsTalkingT; + + s32 OnscreenCharacterCount; + scene_view_character_data OnscreenCharacters[16]; + + //- sixten: input per frame platform_event_list *EventList; r32 dtForFrame; - scene_runtime Runtime; - textbox Textbox; + //- sixten: temporary texture hub render_handle BackgroundTexture; - - s32 TargetCharacter; - render_handle TestHappy; render_handle TestNormal; + render_handle MonikaLeaning; - s32 CharacterCount; - scene_view_character_data OnscreenCharacters[16]; }; static void SV_SetState(scene_view *View); static scene_view *SV_GetState(); + static void SV_NewFrame(scene_view *View, platform_event_list *EventList, r32 dtForFrame); +static void SV_Reset(void); static void SV_SetCurrentSource(compiled_scene *Compiled); -static void SV_Init(scene_view *View, memory_arena *TextboxArena); +static void SV_Init(scene_view *View, arena *TextboxArena); + +static b32 SV_CurrentlyInProc(void); + static void SV_BuildSceneView(vn_input *Input); -static void SV_Update(memory_arena *FrameArena); +static void SV_Update(arena *FrameArena); #endif //VN_SCENE_VIEW_H diff --git a/code/vn_text_op.h b/code/vn_text_op.h index ca754ba..1b668d6 100644 --- a/code/vn_text_op.h +++ b/code/vn_text_op.h @@ -359,7 +359,7 @@ static b32 StringIsWhitespace(string String) return(Result); } -static text_op TextOpFromAction(memory_arena *Arena, string String, +static text_op TextOpFromAction(arena *Arena, string String, text_edit_state *State, text_action *Action, range1_s64_array *Lines = 0, s64 LastColumnIndex = 0) { @@ -413,42 +413,6 @@ static text_op TextOpFromAction(memory_arena *Arena, string String, { IgnoreFirstWhitespace = false; } - -#if 0 - u8 *LineBegin = Line.Data; - u8 *LineEnd = LineBegin+Line.Count; - u8 *Char = (Action->Delta > 0)?LineBegin:LineEnd; - - if(Action->Delta > 0) - { - for(;Char <= LineEnd; Char += 1) - { - if(Char == LineEnd) - { - goto FoundLine; - } - if(!IsWhitespace(*Char)) - { - break; - } - } - } - else if(Action->Delta < 0) - { - for(;LineBegin <= Char; Char -= 1) - { - if(!IsWhitespace(*Char)) - { - break; - } - - if(Char == LineBegin) - { - goto FoundLine; - } - } - } -#endif } } diff --git a/code/vn_tokenizer.cpp b/code/vn_tokenizer.cpp index 66d0ab0..72420c5 100644 --- a/code/vn_tokenizer.cpp +++ b/code/vn_tokenizer.cpp @@ -7,7 +7,7 @@ static string T_StringFromToken(string Text, token Token) return(Result); } -static void T_TokenChunkListPush(memory_arena *Arena, token_chunk_list *List, token Token, s64 MaxTokenCountPerNode) +static void T_TokenChunkListPush(arena *Arena, token_chunk_list *List, token Token, s64 MaxTokenCountPerNode) { token_chunk_node *Node = List->Last; if(!Node || Node->Count >= Node->MaxCount) @@ -23,7 +23,7 @@ static void T_TokenChunkListPush(memory_arena *Arena, token_chunk_list *List, to List->Count += 1; } -static token_array T_TokenArrayFromList(memory_arena *Arena, token_chunk_list *List) +static token_array T_TokenArrayFromList(arena *Arena, token_chunk_list *List) { token_array Result = {}; Result.Tokens = PushArrayNoClear(Arena, token, List->Count); @@ -40,7 +40,7 @@ static token_array T_TokenArrayFromList(memory_arena *Arena, token_chunk_list *L //////////////////////////////// //~ sixten: Tokenizer Message Functions -static void T_MessageListPush(memory_arena *Arena, tokenizer_message_list *List, tokenizer_message_kind Kind, s64 Offset, string String) +static void T_MessageListPush(arena *Arena, tokenizer_message_list *List, tokenizer_message_kind Kind, s64 Offset, string String) { tokenizer_message *Message = PushStructNoClear(Arena, tokenizer_message); Message->Kind = Kind; @@ -52,7 +52,7 @@ static void T_MessageListPush(memory_arena *Arena, tokenizer_message_list *List, //////////////////////////////// //~ sixten: Text -> Token Functions -static tokenize_result T_TokenizeFromText(memory_arena *Arena, string Text, tokenizer_filter_function *ExcludeFilter) +static tokenize_result T_TokenizeFromText(arena *Arena, string Text, tokenizer_filter_function *ExcludeFilter) { temporary_memory Scratch = GetScratch(&Arena, 1); token_chunk_list Tokens = {}; diff --git a/code/vn_tokenizer.h b/code/vn_tokenizer.h index 245971c..b103463 100644 --- a/code/vn_tokenizer.h +++ b/code/vn_tokenizer.h @@ -148,15 +148,15 @@ inline b32 T_IsInvalid(token_kind Kind) { return(Kind == TokenKind_None || //////////////////////////////// //~ sixten: Token Type Functions static string T_StringFromToken(string Text, token Token); -static void T_TokenChunkListPush(memory_arena *Arena, token_chunk_list *List, token Token, s64 MaxTokenCountPerNode); -static token_array T_TokenArrayFromChunkList(memory_arena *Arena, token_chunk_list *List); +static void T_TokenChunkListPush(arena *Arena, token_chunk_list *List, token Token, s64 MaxTokenCountPerNode); +static token_array T_TokenArrayFromChunkList(arena *Arena, token_chunk_list *List); //////////////////////////////// //~ sixten: Tokenizer Message Functions -static void T_MessageListPush(memory_arena *Arena, tokenizer_message_list *List, tokenizer_message_kind Kind, s64 Offset, string String); +static void T_MessageListPush(arena *Arena, tokenizer_message_list *List, tokenizer_message_kind Kind, s64 Offset, string String); //////////////////////////////// //~ sixten: Text -> Token Functions -static tokenize_result T_TokenizeFromText(memory_arena *Arena, string Text, tokenizer_filter_function *ExcludeFilter = 0); +static tokenize_result T_TokenizeFromText(arena *Arena, string Text, tokenizer_filter_function *ExcludeFilter = 0); #endif //VN_TOKENIZER_H diff --git a/code/vn_ui.cpp b/code/vn_ui.cpp index 6cb0531..93e324c 100644 --- a/code/vn_ui.cpp +++ b/code/vn_ui.cpp @@ -36,7 +36,7 @@ inline platform_event_list *UI_EventList(void) return(UI_GetState()->EventList); } -inline memory_arena *UI_FrameArena(void) +inline arena *UI_FrameArena(void) { return(UI_GetState()->FrameArena); } @@ -795,8 +795,8 @@ static void UI_LayoutBox(ui_box *Box) static void UI_Init(ui *UI) { - UI->Arena = ArenaAllocate(Gigabytes(1)); - UI->FrameArena = ArenaAllocate(Gigabytes(1)); + UI->Arena = ArenaAlloc(Kilobytes(4), true); + UI->FrameArena = ArenaAlloc(Kilobytes(16), true); } static void UI_BeginBuild(v2 ScreenDim) diff --git a/code/vn_ui.h b/code/vn_ui.h index b0243f0..b2f2902 100644 --- a/code/vn_ui.h +++ b/code/vn_ui.h @@ -130,8 +130,8 @@ struct ui_signal struct ui { - memory_arena *Arena; - memory_arena *FrameArena; + arena *Arena; + arena *FrameArena; ui_box *FirstFreeBox; ui_box *LastFreeBox; @@ -165,7 +165,7 @@ inline ui *UI_GetState(void); inline ui_key UI_HotKey(void); inline ui_key UI_ActiveKey(void); inline platform_event_list *UI_EventList(void); -inline memory_arena *UI_FrameArena(void); +inline arena *UI_FrameArena(void); inline v2 UI_MouseP(void); inline glyph_atlas *UI_GlyphAtlas(void); diff --git a/code/vn_workspace.cpp b/code/vn_workspace.cpp index 8bbfddb..cba0e22 100644 --- a/code/vn_workspace.cpp +++ b/code/vn_workspace.cpp @@ -1,8 +1,6 @@ -#include "vn_workspace_view.cpp" -#include "vn_workspace_editor.cpp" -#include "vn_workspace_text_editor.cpp" -#include "vn_workspace_character_editor.cpp" #include "vn_workspace_commands.cpp" +#include "vn_workspace_view.cpp" +#include "vn_workspace_text_editor.cpp" //- sixten: State management per_thread workspace *ThreadLocal_Workspace; @@ -13,7 +11,6 @@ static workspace_keybind Workspace_Keybinds[] = {Key_L, PlatformModifier_Ctrl, W_Command_SplitPanelVertical}, {Key_O, PlatformModifier_Ctrl, W_Command_OpenView, W_View_TextEditor}, - {Key_T, PlatformModifier_Ctrl, W_Command_Test}, #if VN_INTERNAL {Key_U, PlatformModifier_Ctrl|PlatformModifier_Shift, W_Command_ToggleRenderUIDebugRects}, @@ -30,7 +27,7 @@ static workspace *W_GetState(void) return(ThreadLocal_Workspace); } -static memory_arena *W_FrameArena(void) +static arena *W_FrameArena(void) { return(ThreadLocal_Workspace->FrameArena); } @@ -104,7 +101,7 @@ static void W_ProcessKeyBinds() //- sixten: Builder code -static ui_signal W_BuildToolbarButton(char *Text, toolbar_menu Menu) +static ui_signal W_BuildToolbarButton(char *Text, workspace_toolbar_menu Menu) { workspace *Workspace = W_GetState(); @@ -123,7 +120,7 @@ static ui_signal W_BuildToolbarButton(char *Text, toolbar_menu Menu) ui_signal Signal = UI_SignalFromBox(Box); - if(Workspace->Menu == ToolbarMenu_None) + if(Workspace->Menu == W_ToolbarMenu_None) { if(Signal.Clicked) { @@ -178,7 +175,7 @@ static ui_signal W_BuildMenuItem(u32 Icon, char *Text, char *Shortcut) return(Signal); } -static void W_BuildToolbar() +static void W_BuildToolbar(void) { workspace *Workspace = W_GetState(); @@ -191,12 +188,12 @@ static void W_BuildToolbar() UI_Parent(ToolbarBox) { - W_BuildToolbarButton("Panel", ToolbarMenu_Panel); - W_BuildToolbarButton("View", ToolbarMenu_View); - W_BuildToolbarButton("Window", ToolbarMenu_Window); + W_BuildToolbarButton("Panel", W_ToolbarMenu_Panel); + W_BuildToolbarButton("View", W_ToolbarMenu_View); + W_BuildToolbarButton("Window", W_ToolbarMenu_Window); } - if(Workspace->Menu != ToolbarMenu_None) + if(Workspace->Menu != W_ToolbarMenu_None) { r32 MenuTransition = Workspace->MenuTransition; @@ -219,20 +216,20 @@ static void W_BuildToolbar() UI_CornerRadius(2) UI_Size(UI_Percent(1, 1), UI_Pixels(25, 1)) { - if(Workspace->Menu == ToolbarMenu_Panel) + if(Workspace->Menu == W_ToolbarMenu_Panel) { if(W_BuildMenuItem(FontIcon_ResizeHorizontal, "Split Horizontal", "Ctrl + P").Clicked) { W_IssueCommand(W_Command_SplitPanelHorizontal); - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } if(W_BuildMenuItem(FontIcon_ResizeVertical, "Split Vertical", "Ctrl + L").Clicked) { W_IssueCommand(W_Command_SplitPanelVertical); - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } } - else if(Workspace->Menu == ToolbarMenu_View) + else if(Workspace->Menu == W_ToolbarMenu_View) { workspace_panel *CurrentPanel = Workspace->CurrentPanel; @@ -243,49 +240,45 @@ static void W_BuildToolbar() if(W_BuildMenuItem(FontIcon_None, "Welcome", "").Clicked) { W_CreateNewView(W_View_Startup, CurrentPanel); - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } if(W_BuildMenuItem(FontIcon_Pencil, "Script Editor", "Ctrl + O").Clicked) { W_CreateNewView(W_View_TextEditor, CurrentPanel); - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } if(W_BuildMenuItem(FontIcon_Terminal, "Scene View", "").Clicked) { W_CreateNewView(W_View_SceneView, CurrentPanel); - Workspace->Menu = ToolbarMenu_None; - } - if(W_BuildMenuItem(FontIcon_User, "Character Editor", "").Clicked) - { - W_CreateNewView(W_View_CharacterEditor, CurrentPanel); - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } + if(W_BuildMenuItem(FontIcon_Wrench, "Settings", "").Clicked) { W_CreateNewView(W_View_Settings, CurrentPanel); - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } } - else if(Workspace->Menu == ToolbarMenu_Window) - { + else if(Workspace->Menu == W_ToolbarMenu_Window) + if(W_BuildMenuItem(FontIcon_WindowMaximize, "ToggleFullscreen", "Alt + Enter").Clicked) - { - Platform.ToggleFullscreen(); - Workspace->Menu = ToolbarMenu_None; - } + { + Platform.ToggleFullscreen(); + Workspace->Menu = W_ToolbarMenu_None; } - - AC_AnimateValueDirect(1, 0.1, &Workspace->MenuTransition); } + AC_AnimateValueDirect(1, 0.1, &Workspace->MenuTransition); + // sixten: Unless the mouse press was captured, we close the menu. if(Platform_KeyPress(Workspace->EventList, Key_MouseLeft)) { - Workspace->Menu = ToolbarMenu_None; + Workspace->Menu = W_ToolbarMenu_None; } } } + //- sixten: Panels static workspace_panel *W_CreateNewPanel(workspace_panel *Parent) { @@ -762,9 +755,9 @@ static void W_Init(workspace *Workspace) { W_SetState(Workspace); - Workspace->FrameArena = ArenaAllocate(Gigabytes(1)); - Workspace->CommandArena = ArenaAllocate(Gigabytes(1)); - Workspace->PanelArena = ArenaAllocate(Gigabytes(1)); + Workspace->FrameArena = ArenaAlloc(Kilobytes(32), true); + Workspace->CommandArena = ArenaAlloc(Kilobytes(4), true); + Workspace->PanelArena = ArenaAlloc(Kilobytes(4), true); Workspace->RootPanel = Workspace->CurrentPanel = W_CreateNewPanel(0); @@ -774,16 +767,13 @@ static void W_Init(workspace *Workspace) } // sixten: build text editor / scene view layout - if(1) + if(0) { W_CreateNewView(W_View_TextEditor, Workspace->RootPanel); W_SplitPanel(Workspace->RootPanel, Axis2_X); W_CreateNewView(W_View_SceneView, Workspace->RootPanel->Last); } - else // sixten: build character editor - { - W_CreateNewView(W_View_CharacterEditor, Workspace->RootPanel); - } + } static void W_Update(workspace *Workspace, vn_render_commands *RenderCommands, diff --git a/code/vn_workspace.h b/code/vn_workspace.h index 0e3ab0c..ab86bb2 100644 --- a/code/vn_workspace.h +++ b/code/vn_workspace.h @@ -7,12 +7,12 @@ //~ sixten: Workspace Types // sixten(TODO): Remove this type entirely. -enum toolbar_menu +enum workspace_toolbar_menu { - ToolbarMenu_None = 0, - ToolbarMenu_Panel, - ToolbarMenu_View, - ToolbarMenu_Window, + W_ToolbarMenu_None = 0, + W_ToolbarMenu_Panel, + W_ToolbarMenu_View, + W_ToolbarMenu_Window, }; struct workspace_panel @@ -71,10 +71,10 @@ struct workspace platform_event_list *EventList; // sixten: General Purpose Allocation - memory_arena *FrameArena; + arena *FrameArena; // sixten: Command Allocation - memory_arena *CommandArena; + arena *CommandArena; workspace_command *FirstFreeCommand; workspace_command *LastFreeCommand; @@ -83,14 +83,14 @@ struct workspace workspace_command *LastCommand; // sixten: Panels - memory_arena *PanelArena; + arena *PanelArena; workspace_panel *FirstFreePanel; workspace_panel *LastFreePanel; workspace_drag_payload_state DragPayloadState; workspace_drag_payload DragPayload; - toolbar_menu Menu; + workspace_toolbar_menu Menu; v2 MenuP; r32 MenuTransition; @@ -98,9 +98,7 @@ struct workspace workspace_panel *CurrentPanel; }; -#include "vn_workspace_editor.h" #include "vn_workspace_text_editor.h" -#include "vn_workspace_character_editor.h" #include "vn_workspace_view.h" //////////////////////////////// @@ -109,7 +107,7 @@ struct workspace //- sixten: State management static void W_SetState(workspace *Workspace); static workspace *W_GetState(void); -static memory_arena *W_FrameArena(void); +static arena *W_FrameArena(void); //- sixten: Commands static void W_IssueCommand(workspace_command_sig *Sig, u64 Argument); @@ -121,9 +119,9 @@ static void W_DeletePanel(workspace_panel *Panel); static void W_SplitPanel(workspace_panel *Panel, axis2 Axis); //- sixten: Builder code -static ui_signal W_BuildToolbarButton(char *Text, toolbar_menu Menu); +static ui_signal W_BuildToolbarButton(char *Text, workspace_toolbar_menu Menu); static ui_signal W_BuildMenuItem(u32 Icon, char *Text, char *Shortcut); -static void W_BuildToolbar(r32 dtForFrame); +static void W_BuildToolbar(void); //- sixten: Workspace static void W_Init(workspace *Workspace); diff --git a/code/vn_workspace_character_editor.cpp b/code/vn_workspace_character_editor.cpp deleted file mode 100644 index 01793fd..0000000 --- a/code/vn_workspace_character_editor.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//////////////////////////////// -//~ sixten: Workspace Character Editor Functions - -static character_editor_entry_data *W_AllocateCharacterEntryData(workspace_view_character_editor *Editor, memory_arena *Arena) -{ - character_editor_entry_data *Result = Editor->FreeList.First; - if(!Result) - { - Result = PushStructNoClear(Arena, character_editor_entry_data); - } - *Result = {}; - return(Result); -} - -static void W_BuildCharacterEditorView(workspace_view *View) -{ - workspace_view_character_editor *Editor = (workspace_view_character_editor *)View->Data; - - //- sixten: check that the entry list is filled out - if(DLLIsEmpty(Editor->List.First)) - { - character_list Characters = CR_GetCharacters(); - for(character_entry *Character = Characters.First; Character != 0; Character = Character->Next) - { - character_editor_entry_data *Data = W_AllocateCharacterEntryData(Editor, View->Arena); - Data->Entry = Character; - - DLLInsertLast(Editor->List.First, Editor->List.Last, Data); - } - } - - UI_WidthFill UI_HeightFill UI_Row() UI_Padding(UI_Em(5, 1)) UI_Column() - { - UI_Spacer(UI_Em(2, 1)); - - // sixten: build character lister - { - UI_SetNextWidth(UI_Percent(1, 1)); - UI_SetNextHeight(UI_Percent(1, 0)); - - UI_Scroll(0, &Editor->ScrollT) - { - UI_Height(UI_Em(2.0f, 1)) UI_CornerRadius(4.0f) - for(character_editor_entry_data *Data = Editor->List.First; Data != 0; Data = Data->Next) - { - character_entry *Entry = Data->Entry; - if(UI_ButtonF("%S", Entry->Name).Clicked) - { - Data->IsOpen = !Data->IsOpen; - } - - AC_AnimateValueDirect(Data->IsOpen, 0.3f, &Data->OpenTransition); - - if(Data->OpenTransition > 0.1f) - { - UI_SetNextHeight(UI_ChildrenSum(Data->OpenTransition, 1)); - UI_Parent(UI_MakeBox(UI_BoxFlag_DrawBorder | - UI_BoxFlag_DrawDropShadow | - UI_BoxFlag_Clip, - StrLit(""))) - { - UI_LabelF("hello"); - UI_LabelF("line"); - UI_LabelF("paint"); - UI_LabelF("color"); - UI_LabelF("design"); - UI_LabelF("address"); - UI_LabelF("brightness"); - } - } - } - } - } - - // sixten: build bottom controls - UI_Spacer(UI_Em(1.5, 1)); - UI_Height(UI_Em(2, 1)) UI_Row() - { - UI_Width(UI_TextContent(15, 1)) UI_CornerRadius(4) - { - UI_SetNextFont(Font_Icons); - ui_signal AddSignal = UI_ButtonF("%U", FontIcon_UserPlus); - if(AddSignal.Hovering) - { - UI_TooltipLabel(StrLit("Add new character"), UI_MouseP()); - } - - UI_Spacer(UI_Em(0.5, 1)); - - UI_SetNextFont(Font_Icons); - ui_signal RemoveSignal = UI_ButtonF("%U", FontIcon_UserTimes); - if(RemoveSignal.Hovering) - { - UI_TooltipLabel(StrLit("Delete selected character"), UI_MouseP()); - } - } - } - UI_Spacer(UI_Em(1.5, 1)); - } -} \ No newline at end of file diff --git a/code/vn_workspace_character_editor.h b/code/vn_workspace_character_editor.h deleted file mode 100644 index 14059fb..0000000 --- a/code/vn_workspace_character_editor.h +++ /dev/null @@ -1,40 +0,0 @@ -/* date = August 27th 2023 3:38 pm */ - -#ifndef VN_WORKSPACE_CHARACTER_EDITOR_H -#define VN_WORKSPACE_CHARACTER_EDITOR_H - -//////////////////////////////// -//~ sixten: Workspace Character Editor Types - -struct character_editor_entry_data -{ - //- sixten: node links - character_editor_entry_data *Next; - character_editor_entry_data *Prev; - - //- sixten: contents - struct character_entry *Entry; - b32 IsOpen; - r32 OpenTransition; -}; - -struct character_editor_processed_entry_list -{ - character_editor_entry_data *First; - character_editor_entry_data *Last; -}; - -struct workspace_view_character_editor -{ - character_editor_processed_entry_list List; - character_editor_processed_entry_list FreeList; - - r32 ScrollT; -}; - -//////////////////////////////// -//~ sixten: Workspace Character Editor Functions - -static void W_BuildCharacterEditorView(workspace_view *View); - -#endif //VN_WORKSPACE_CHARACTER_EDITOR_H diff --git a/code/vn_workspace_editor.cpp b/code/vn_workspace_editor.cpp deleted file mode 100644 index 25aed25..0000000 --- a/code/vn_workspace_editor.cpp +++ /dev/null @@ -1,377 +0,0 @@ -//- sixten: Managing nodes -static workspace_editor_node *Workspace_GetNewEditorNode(workspace_view *View) -{ - Assert(View->Type == W_View_Editor); - - workspace_view_editor *Editor = (workspace_view_editor *)View->Data; - - workspace_editor_node *Result = 0; - - if(DLLIsEmpty(Editor->FirstFreeNode)) - { - Result = PushStruct(View->Arena, workspace_editor_node); - } - else - { - Result = Editor->FirstFreeNode; - DLLRemove(Editor->FirstFreeNode, Editor->LastFreeNode, Result); - } - - if(Result) - { - *Result = {}; - DLLInsertLast(Editor->FirstNode, Editor->LastNode, Result); - } - - return(Result); -} - -//- sixten: Transformations -inline r32 Workspace_ViewToWorld(r32 Offset, r32 Scale, r32 Dim, r32 P) -{ - r32 Result = (P - Dim*0.5)*(1.0/Scale) - Offset; - return(Result); -} - -inline r32 Workspace_WorldToView(r32 Offset, r32 Scale, r32 Dim, r32 P) -{ - r32 Result = (P + Offset)*Scale + Dim*0.5; - return(Result); -} - -inline v2 Workspace_ViewToWorld(v2 Offset, r32 Scale, v2 Dim, v2 P) -{ - v2 Result = (P - Dim*0.5)*(1.0/Scale) - Offset; - return(Result); -} - -inline v2 Workspace_WorldToView(v2 Offset, r32 Scale, v2 Dim, v2 P) -{ - v2 Result = (P + Offset)*Scale + Dim*0.5; - return(Result); -} - -inline r32 Workspace_CalculateScaleFromZoomLevel(r32 ZoomLevel) -{ - r32 PixelsPerUnit = 100.0; - - r32 Scale = PixelsPerUnit*Pow(1.25, ZoomLevel); - return(Scale); -} - -//- sixten: Commands - - -//- sixten: Builder code -static void Workspace_BuildEditorListerDropdown(workspace_editor_lister_dropdown *ListerDropdown) -{ - b32 ActiveInDropdown = false; - - UI_PushBackgroundColor(SetAlpha(Color_Black, 0.3)); - UI_PushBorderColor(SetAlpha(Color_Black, 0.7)); - - r32 HeightTransition = AC_AnimateValueF(1, 0, 0.3, "Editor Lister Dropdown %p", ListerDropdown); - - UI_SetNextSize(UI_Em(15, 1), UI_Em(25*HeightTransition, 1)); - UI_SetNextCornerRadius(4.0); - UI_SetNextFixedP(ListerDropdown->P); - UI_SetNextLayoutAxis(Axis2_Y); - - ui_box *Box = UI_MakeBox(UI_BoxFlag_DrawBackground | - UI_BoxFlag_FloatingX | - UI_BoxFlag_FloatingY | - UI_BoxFlag_Clickable | - UI_BoxFlag_Clip, - StrLit("Editor Lister Dropdown")); - - UI_Parent(Box) - { - - UI_BorderColor(SetAlpha(Color_Grey, 0.7)) - UI_Row() UI_Column() - { - UI_Size(UI_TextContent(15, 1), UI_TextContent(12, 1)) UI_LabelF("Create new node"); - - // sixten: Build search bar - UI_SetNextWidth(UI_Percent(1, 1)); - UI_SetNextHeight(UI_Em(2, 1)); - UI_SetNextCornerRadius(4.0); - UI_SetNextLayoutAxis(Axis2_X); - UI_Parent(UI_MakeBox(UI_BoxFlag_DrawBorder|UI_BoxFlag_DrawBackground, StrLit("Editor Lister Field"))) - { - UI_Spacer(UI_Em(0.8, 1)); - UI_Width(UI_TextContent(1, 1)) UI_Font(Font_Icons) UI_LabelF("%U", FontIcon_Filter); - UI_Width(UI_Percent(1, 0)) - { - UI_MakeBox(0, StrLit("")); - } - } - - struct lister_option - { - char *Text; - u32 Icons; - }; - - lister_option Options[] = - { - {"Text", FontIcon_Pencil}, - {"Branch", FontIcon_Menu}, - }; - - for(s32 OptionIndex = 0; - OptionIndex < ArrayCount(Options); - ++OptionIndex) - { - lister_option *Option = Options + OptionIndex; - - UI_SetNextSize(UI_Percent(1, 1), UI_Em(2, 1)); - UI_SetNextLayoutAxis(Axis2_X); - ui_box *ClickableBox = UI_MakeBoxF(UI_BoxFlag_Clickable, "Editor Lister %s", Option->Text); - - ui_signal Signal = UI_SignalFromBox(ClickableBox); - - if(AreEqual(UI_ActiveKey(), ClickableBox->Key)) - { - ActiveInDropdown = true; - } - - UI_Parent(ClickableBox) - UI_Height(UI_Percent(1, 1)) - { - b32 IsHot = AreEqual(UI_HotKey(), ClickableBox->Key); - r32 TargetHot = IsHot*0.8; - - UI_SetNextCornerRadius(3.0); - UI_SetNextSize(UI_Percent(1, 1), UI_Percent(1, 1)); - UI_SetNextBackgroundColor(SetAlpha(Theme_HighlightBorderColor, - AC_AnimateValueF(TargetHot, TargetHot, 0.1, "Editor Lister %s%p", - Option->Text, ListerDropdown))); - UI_SetNextLayoutAxis(Axis2_X); - ui_box *HighlightBox = UI_MakeBox(UI_BoxFlag_DrawBackground, StrLit("")); - - UI_Parent(HighlightBox) - UI_Padding(UI_Em(0.8, 1)) - { - UI_Width(UI_TextContent(0, 1)) - UI_Font(Font_Icons) UI_MakeBoxF(UI_BoxFlag_DrawText, "%U", Option->Icons); - UI_Spacer(UI_Em(0.6, 1)); - UI_Width(UI_TextContent(0, 1)) UI_MakeBoxF(UI_BoxFlag_DrawText, "%s", Option->Text); - - if(Signal.Clicked) - { - // sixten(TODO): Issue the requested command. - ListerDropdown->Open = false; - } - } - } - } - } - - ui_signal Signal = UI_SignalFromBox(Box); - if(AreEqual(UI_ActiveKey(), Box->Key)) - { - ActiveInDropdown = true; - } - } - UI_PopBackgroundColor(); - UI_PopBorderColor(); - - if(!ActiveInDropdown && !AreEqual(UI_ActiveKey(), UI_EmptyKey())) - { - ListerDropdown->Open = false; - } -} - -static void Workspace_EditorDrawCallback(render_group *Group, glyph_atlas *Atlas, ui_box *Box, void *Data) -{ - workspace_view_editor *Editor = (workspace_view_editor *)Data; - - r32 Scale = Editor->Scale; - - v4 LineColor = Theme_BorderColor; - - v2 Dim = DimOfRange(Box->Rect); - - s32 VerticalLineCount = Dim.x / Scale + 4; - for(s32 LineIndex = -VerticalLineCount/2; - LineIndex < VerticalLineCount/2; - ++LineIndex) - { - r32 OffsetX = Workspace_WorldToView(Editor->Offset.x, Scale, Dim.x, LineIndex - (s32)Editor->Offset.x); - v2 Min = Box->Rect.Min + V2(OffsetX, 0); - v2 Max = Min + V2(1.5, Dim.y); - PushQuad(Group, Range2R32(Min, Max), LineColor, 0, 1.2, 0); - } - - s32 HorizontalLineCount = Dim.y / Scale + 4; - for(s32 LineIndex = -HorizontalLineCount/2; - LineIndex < HorizontalLineCount/2; - ++LineIndex) - { - r32 OffsetY = Workspace_WorldToView(Editor->Offset.y, Scale, Dim.y, LineIndex - (s32)Editor->Offset.y); - v2 Min = Box->Rect.Min + V2(0, OffsetY); - v2 Max = Min + V2(Dim.x, 1.5); - - PushQuad(Group, Range2R32(Min, Max), LineColor, 0, 1.2, 0); - } -} - -static void Workspace_BuildEditor(workspace_view *View) -{ - workspace *Workspace = W_GetState(); - - workspace_view_editor *Editor = (workspace_view_editor *)View->Data; - - UI_SetNextWidth(UI_Percent(1, 1)); - UI_SetNextHeight(UI_Percent(1, 1)); - - ui_box *EditorBox = UI_MakeBoxF(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "Workspace Editor %p", View); - UI_EquipBoxCustomDrawCallback(EditorBox, Workspace_EditorDrawCallback, Editor); - - r32 AnimatedZoomLevel = AC_AnimateValueF(Editor->ZoomLevel, 0, 0.25, "Workspace Editor Zoom"); - Editor->Scale = Workspace_CalculateScaleFromZoomLevel(AnimatedZoomLevel); - - v2 EditorDim = DimOfRange(EditorBox->Rect); - - UI_Parent(EditorBox) - { - // sixten: Build the node boxes. - for(workspace_editor_node *Node = Editor->FirstNode; - Node != 0; - Node = Node->Next) - { - v2 ViewDim = V2(2, 1.5)*Editor->Scale; - v2 ViewP = Workspace_WorldToView(Editor->Offset, Editor->Scale, EditorDim, Node->P) - ViewDim*0.5; - - UI_SetNextSize(UI_Pixels(ViewDim.x, 1), UI_Pixels(ViewDim.y, 1)); - UI_SetNextFixedP(ViewP); - UI_SetNextLayoutAxis(Axis2_Y); - - Node->Box = UI_MakeBoxF(UI_BoxFlag_DrawBackground | - UI_BoxFlag_DrawBorder | - UI_BoxFlag_FloatingX | - UI_BoxFlag_FloatingY | - UI_BoxFlag_DrawDropShadow, - "Workspace Editor Node %p", Node); - - UI_Parent(Node->Box) - { - UI_SetNextBackgroundColor(LinearBlend(Theme_BackgroundColor, Color_Black, 0.3)); - UI_SetNextLayoutAxis(Axis2_X); - UI_SetNextSize(UI_Percent(1, 1), UI_Em(1.8, 1)); - Node->TitleBox = UI_MakeBoxF(UI_BoxFlag_DrawBackground | - UI_BoxFlag_DrawBorder | - UI_BoxFlag_Clickable, - "Workspace Editor Node Title"); - - UI_Parent(Node->TitleBox) - { - UI_Spacer(UI_Em(0.5, 1)); - - UI_Width(UI_TextContent(0, 1)) UI_Font(Font_Bold) UI_LabelF("Node"); - UI_Spacer(UI_Percent(1, 0)); - - UI_SetNextSize(UI_Em(1.8, 1), UI_Percent(1, 1)); - UI_SetNextFont(Font_Icons); - Node->CloseBox = UI_MakeBoxF(UI_BoxFlag_DrawText, "%U", FontIcon_Cancel); - } - } - } - - if(Editor->ListerDropdown.Open) - { - Workspace_BuildEditorListerDropdown(&Editor->ListerDropdown); - } - } - - // sixten: Get input from boxes. - { - workspace_editor_node *Next = 0; - for(workspace_editor_node *Node = Editor->FirstNode; - Node != 0; - Node = Next) - { - Next = Node->Next; - - ui_signal Signal = UI_SignalFromBox(Node->TitleBox); - if(Signal.Dragging) - { - if(Signal.Pressed) - { - UI_StoreDragV2(Node->P); - } - - v2 StartP = UI_GetDragV2(); - v2 EndP = StartP + Signal.DragDelta*(1.0 / Editor->Scale); - - Node->P = EndP; - } - - if(Signal.Dragging || Signal.Hovering) - { - Platform.SetCursor(PlatformCursor_ArrowAll); - } - } - } - - // sixten: Process panning and zooming of the editor. - ui_signal Signal = UI_SignalFromBox(EditorBox); - { - if(Signal.Dragging) - { - if(Signal.Pressed) - { - UI_StoreDragV2(Editor->Offset); - } - - v2 StartOffset = UI_GetDragV2(); - v2 EndOffset = StartOffset + Signal.DragDelta*(1.0 / Editor->Scale); - - Editor->Offset = EndOffset; - - // sixten: Update node positions, as to not get a one frame delay. - for(workspace_editor_node *Node = 0; - Node != 0; - Node = Node->Next) - { - v2 ViewDim = V2(2, 1.5)*Editor->Scale; - v2 ViewP = Workspace_WorldToView(Editor->Offset, Editor->Scale, EditorDim, Node->P) - ViewDim*0.5; - - Node->Box->FixedP = ViewP; - } - } - } - - for(platform_event *Event = Workspace->EventList->First; - Event != 0; - Event = Event->Next) - { - if(Event->Type == PlatformEvent_MouseScroll) - { - if(Signal.Dragging) - { - UI_StoreDragV2(Editor->Offset); - UI_UpdateDragStartP(); - } - - Editor->ZoomLevel = Clamp(Editor->ZoomLevel + Event->Scroll.y, -4, 5); - } - } - - // sixten: Process shortcuts. - if(Platform_KeyPress(Workspace->EventList, Key_Space, PlatformModifier_Ctrl)) - { - workspace_editor_lister_dropdown *ListerDropdown = &Editor->ListerDropdown; - - if(ListerDropdown->Open) - { - ListerDropdown->Open = false; - } - else if(InRange(EditorBox->Rect, UI_GetState()->MouseP)) - { - ListerDropdown->Open = true; - ListerDropdown->P = UI_GetState()->MouseP - EditorBox->Rect.Min; - } - } -} diff --git a/code/vn_workspace_editor.h b/code/vn_workspace_editor.h deleted file mode 100644 index 3cc15ab..0000000 --- a/code/vn_workspace_editor.h +++ /dev/null @@ -1,63 +0,0 @@ -/* date = May 13th 2023 6:20 pm */ - -#ifndef VN_WORKSPACE_EDITOR_H -#define VN_WORKSPACE_EDITOR_H - -/* sixten(NOTE): Node types -* -* Text(String, opt. Character) -> Node -* Branch(Strings[0..n]) -> Nodes[0..n] -* -*/ - -enum workspace_editor_node_type -{ - Workspace_EditorNode_None, - Workspace_EditorNode_Start, - Workspace_EditorNode_Text, - Workspace_EditorNode_Branch, -}; - -struct workspace_editor_node -{ - workspace_editor_node_type Type; - - workspace_editor_node *Next; - workspace_editor_node *Prev; - - ui_box *Box; - ui_box *TitleBox; - ui_box *CloseBox; - - v2 P; -}; - -struct workspace_editor_lister_dropdown -{ - // sixten: Input field - char InputField[128]; - s32 InputFieldUsed; - b32 InputFieldSelected; - - // sixten: Properties - b32 Open; - v2 P; -}; - -//- sixten: Managing nodes -static workspace_editor_node *Workspace_GetNewEditorNode(struct workspace_view *View); - -//- sixten: Transformations -inline v2 Workspace_ViewToWorld(v2 Offset, r32 Scale, v2 Dim, v2 P); -inline v2 Workspace_WorldToView(v2 Offset, r32 Scale, v2 Dim, v2 P); -inline r32 Workspace_CalculateScaleFromZoomLevel(r32 ZoomLevel); - -//- sixten: Lister dropdown -static void Workspace_OpenListerDropdown(v2 MouseP); - -//- sixten: Builder code -static void Workspace_BuildEditorListerDropdown(workspace_editor_lister_dropdown *ListerDropdown); -static void Workspace_EditorDrawCallback(render_group *Group, glyph_atlas *Atlas, ui_box *Box, void *Data); -static void Workspace_BuildEditor(struct workspace_view *View); - -#endif //VN_WORKSPACE_EDITOR_H diff --git a/code/vn_workspace_text_editor.cpp b/code/vn_workspace_text_editor.cpp index 21da7e8..7690dc6 100644 --- a/code/vn_workspace_text_editor.cpp +++ b/code/vn_workspace_text_editor.cpp @@ -4,7 +4,7 @@ static mutable_string MutableStringAllocate(u64 Size) { mutable_string Result = {}; - Result.Arena = ArenaAllocate(Size); + Result.Arena = ArenaAlloc(Size); ArenaSetAlign(Result.Arena, 1); Result.String = MakeString(PushArray(Result.Arena, u8, 1), 0LL); return(Result); @@ -27,7 +27,7 @@ static void MutableStringReplaceRange(mutable_string *MutString, string ReplaceS } else if(NewCount < MutString->String.Count) { - ArenaPopTo(MutString->Arena, sizeof(memory_arena)+NewCount+1); + ArenaPopTo(MutString->Arena, sizeof(arena)+NewCount+1); } Move(MutString->String.Data+Range.Min+ReplaceString.Count, MutString->String.Data+Range.Max, MutString->String.Count-Range.Min-DimOfRange(Range)); @@ -40,7 +40,7 @@ static void MutableStringReplaceRange(mutable_string *MutString, string ReplaceS //////////////////////////////// //~ sixten: History & Undo Functions -static history_entry HistoryEntry(memory_arena *Arena, string ReplaceString, range1_s64 Range) +static history_entry HistoryEntry(arena *Arena, string ReplaceString, range1_s64 Range) { // sixten(TODO): proper memory management, right now we just keep appending to the arena, which works but never frees any memory history_entry Entry = {}; @@ -49,7 +49,7 @@ static history_entry HistoryEntry(memory_arena *Arena, string ReplaceString, ran return(Entry); } -static void AppendToHistory(memory_arena *Arena, history_list *List, history_entry Forward, history_entry Backward) +static void AppendToHistory(arena *Arena, history_list *List, history_entry Forward, history_entry Backward) { // sixten(TODO): proper memory management, right now we just keep appending to the arena, which works but never frees any memory history_node *Node = PushStructNoClear(Arena, history_node); @@ -62,7 +62,7 @@ static void AppendToHistory(memory_arena *Arena, history_list *List, history_ent //////////////////////////////// //~ sixten: Workspace Text Editing Functions -static workspace_text_data W_TextDataFromString(memory_arena *Arena, string Text) +static workspace_text_data W_TextDataFromString(arena *Arena, string Text) { temporary_memory Scratch = GetScratch(&Arena, 1); @@ -426,11 +426,14 @@ UI_CUSTOM_DRAW_CALLBACK(W_TextEditorListerInputCallback) } } -static b32 W_BuildTextEditorListerItem(string Text, u32 Icon) +static b32 W_BuildTextEditorListerItem(string Text, u32 Icon, b32 Selected, b32 EnterPressed) { b32 Result = false; UI_SetNextLayoutAxis(Axis2_X); UI_SetNextHoverCursor(PlatformCursor_Hand); + r32 SelectedT = AC_AnimateValueF(Selected, 0, 0.3f, "Lister Item %S", Text); + UI_SetNextBackgroundColor(LinearBlend(Theme_BackgroundColor, Theme_HighlightBorderColor, SelectedT*0.5)); + UI_SetNextBorderColor(LinearBlend(Theme_BorderColor, Theme_HighlightBorderColor, SelectedT)); ui_box *Container = UI_MakeBoxF(UI_BoxFlag_DrawBorder | UI_BoxFlag_DrawBackground | UI_BoxFlag_Clickable | @@ -445,7 +448,7 @@ static b32 W_BuildTextEditorListerItem(string Text, u32 Icon) } ui_signal Signal = UI_SignalFromBox(Container); - if(Signal.Clicked) + if(Signal.Clicked || Selected&&EnterPressed) { Result = true; } @@ -460,6 +463,9 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie { UI_Height(UI_Em(2, 1)) { + b32 EnterPressed = Platform_KeyPress(UI_EventList(), Key_Return); + s32 SelectedItemDelta = 0; + //- sixten: filename input field if(W_ViewIsCurrent(View)) { @@ -471,23 +477,30 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie if(IsValid(&Action)) { text_op Op = TextOpFromAction(Scratch.Arena, MakeString(Editor->ListerInput, Editor->ListerInputUsed), &Editor->ListerInputEditState, &Action); - - string Left = MakeString(Editor->ListerInput, Op.Range.Min); - string Right = MakeString(Editor->ListerInput + Op.Range.Max, Editor->ListerInputUsed - Op.Range.Max); - - u64 NewStringSize = Left.Count + Right.Count + Op.ReplaceString.Count; - char *NewString = PushArray(Scratch.Arena, char, NewStringSize); - Copy(NewString, Left.Data, Left.Count); - Copy(NewString + Left.Count, Op.ReplaceString.Data, Op.ReplaceString.Count); - Copy(NewString + Left.Count + Op.ReplaceString.Count, Right.Data, Right.Count); - - Editor->ListerInputUsed = Minimum(ArrayCount(Editor->ListerInput), NewStringSize); - Copy(Editor->ListerInput, NewString, Editor->ListerInputUsed); - - Editor->ListerInputEditState.Cursor = Minimum(Op.NewCursor, Editor->ListerInputUsed); - Editor->ListerInputEditState.Mark = Minimum(Op.NewMark, Editor->ListerInputUsed); + if(Op.NewCursor >= 0 && Op.NewMark >= 0) + { + string Left = MakeString(Editor->ListerInput, Op.Range.Min); + string Right = MakeString(Editor->ListerInput + Op.Range.Max, Editor->ListerInputUsed - Op.Range.Max); + + u64 NewStringSize = Left.Count + Right.Count + Op.ReplaceString.Count; + char *NewString = PushArray(Scratch.Arena, char, NewStringSize); + Copy(NewString, Left.Data, Left.Count); + Copy(NewString + Left.Count, Op.ReplaceString.Data, Op.ReplaceString.Count); + Copy(NewString + Left.Count + Op.ReplaceString.Count, Right.Data, Right.Count); + Editor->ListerInputUsed = Minimum(ArrayCount(Editor->ListerInput), NewStringSize); + Copy(Editor->ListerInput, NewString, Editor->ListerInputUsed); + + Editor->ListerInputEditState.Cursor = Minimum(Op.NewCursor, Editor->ListerInputUsed); + Editor->ListerInputEditState.Mark = Minimum(Op.NewMark, Editor->ListerInputUsed); + Platform_ConsumeEvent(UI_EventList(), Event); + } } } + + if(Event->Type == PlatformEvent_Press && (Event->Key == Key_Up || Event->Key == Key_Down)) + { + SelectedItemDelta = Event->Key == Key_Up ? -1 : 1; + } } } @@ -506,7 +519,7 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie UI_Padding(UI_Percent(1, 0)); UI_SetNextWidth(UI_TextContent(20, 1)); - if(UI_ButtonF("Open/Create").Clicked || Platform_KeyPress(UI_EventList(), Key_Return)) + if(UI_ButtonF("Open/Create").Clicked || EnterPressed) { ListerAction.HasRequestedFile = true; ListerAction.Name = MakeString(Editor->ListerInput, Editor->ListerInputUsed); @@ -514,15 +527,21 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie } } + s32 ListerCount = 0; + //- sixten: display "parent directory button" s64 LastSlash = LastIndexOf(Editor->Path, '/'); if(LastSlash != -1) { - if(W_BuildTextEditorListerItem(StrLit("Parent Directory"), FontIcon_Reply)) + b32 BackspacePressed = Editor->ListerInputUsed == 0 && Platform_KeyPress(UI_EventList(), Key_Backspace); + if(W_BuildTextEditorListerItem(StrLit("Parent Directory"), FontIcon_Reply, Editor->SelectedItem == ListerCount, EnterPressed) || + BackspacePressed) { Editor->Path = Prefix(Editor->Path, LastSlash); Editor->ListerInputUsed = 0; + Editor->SelectedItem = -1; } + ListerCount += 1; } platform_file_info FileInfo; platform_file_iter *FileIter; @@ -537,11 +556,14 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie { if(FileInfo.IsDirectory) { - if(W_BuildTextEditorListerItem(FileInfo.Name, FontIcon_Folder)) + if(W_BuildTextEditorListerItem(FileInfo.Name, FontIcon_Folder, Editor->SelectedItem == ListerCount, EnterPressed)) { Editor->Path = PushFormat(View->Arena, "%S/%S", Editor->Path, FileInfo.Name); Editor->ListerInputUsed = 0; + Editor->SelectedItem = -1; + ListerAction.HasRequestedFile = false; // sixten: if we have selected a folder, but typed a name we want to open the folder. } + ListerCount += 1; } } } @@ -554,15 +576,32 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie { if(!FileInfo.IsDirectory) { - if(W_BuildTextEditorListerItem(FileInfo.Name, FontIcon_Document)) + if(W_BuildTextEditorListerItem(FileInfo.Name, FontIcon_Document, Editor->SelectedItem == ListerCount, EnterPressed)) { ListerAction.HasRequestedFile = true; + Editor->SelectedItem = -1; ListerAction.Name = PushString(View->Arena, FileInfo.Name); ListerAction.Path = Editor->Path; } + ListerCount += 1; } } } + + //- sixten: update selected item + if(SelectedItemDelta != 0) + { + Editor->SelectedItem += SelectedItemDelta; + if(Editor->SelectedItem < 0) + { + Editor->SelectedItem += ListerCount; + } + else if(Editor->SelectedItem >= ListerCount) + { + Editor->SelectedItem -= ListerCount; + } + } + Platform.EndFileIter(FileIter); } } @@ -646,10 +685,15 @@ static void W_BuildTextEditor(workspace_view *View) s32 LineMarginDigitsRequired = 6; r32 LineMarginWidth = (LineMarginDigitsRequired)*GlyphAdvance; - b32 InFileListMode = AreEqual(Editor->FileName, StrLit("")); if(InFileListMode) { + //- sixten: handle esc to close + if(Platform_KeyPress(UI_EventList(), Key_Escape)) + { + W_IssueCommand(W_Command_CloseView, PointerToU64(View)); + } + //- sixten: build & handle file lister workspace_text_editor_lister_action Action = W_BuildTextEditorLister(View, Editor); if(Action.HasRequestedFile) @@ -677,6 +721,8 @@ static void W_BuildTextEditor(workspace_view *View) { Editor->FileName = Action.Name; Editor->FilePath = Action.Path; + + Editor->SelectedItem = -1; } } } diff --git a/code/vn_workspace_text_editor.h b/code/vn_workspace_text_editor.h index 16455b6..586499a 100644 --- a/code/vn_workspace_text_editor.h +++ b/code/vn_workspace_text_editor.h @@ -8,7 +8,7 @@ struct mutable_string { - memory_arena *Arena; + arena *Arena; string String; }; @@ -54,7 +54,7 @@ struct workspace_text_editor_lister_action struct workspace_view_text_editor { // sixten: processed text - memory_arena *ProcessingArena; + arena *ProcessingArena; token_array Tokens; range1_s64_array Lines; compiled_scene Compiled; @@ -72,7 +72,7 @@ struct workspace_view_text_editor r32 FontSize; // sixten: history - memory_arena *HistoryArena; + arena *HistoryArena; history_list History; history_node *SavePoint; @@ -90,6 +90,7 @@ struct workspace_view_text_editor u8 ListerInput[256]; s32 ListerInputUsed; text_edit_state ListerInputEditState; + s32 SelectedItem; }; //////////////////////////////// @@ -102,13 +103,13 @@ static void MutableStringReplaceRange(mutable_string *String, string ReplaceStri //////////////////////////////// //~ sixten: History & Undo Functions -static history_entry HistoryEntry(memory_arena *Arena, string ReplaceString, range1_s64 Range); -static void AppendToHistory(memory_arena *Arena, history_list *List, history_entry Forward, history_entry Backward); +static history_entry HistoryEntry(arena *Arena, string ReplaceString, range1_s64 Range); +static void AppendToHistory(arena *Arena, history_list *List, history_entry Forward, history_entry Backward); //////////////////////////////// //~ sixten: Workspace Text Editing Functions -static workspace_text_data W_TextDataFromString(memory_arena *Arena, string Text); +static workspace_text_data W_TextDataFromString(arena *Arena, string Text); static void W_TextEditorApplyChanges(workspace_view_text_editor *Editor); static void W_SaveTextEditorToFile(workspace_view_text_editor *Editor); @@ -116,7 +117,7 @@ static void W_SaveTextEditorToFile(workspace_view_text_editor *Editor); //~ sixten: Workspace Text Editor Builder Functions static UI_CUSTOM_DRAW_CALLBACK(W_TextEditorDrawCallback); -static b32 W_BuildTextEditorListerItem(string Text, u32 Icon); +static b32 W_BuildTextEditorListerItem(string Text, u32 Icon, b32 Selected, b32 EnterPressed); static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_view *View, workspace_view_text_editor *Editor); static b32 W_ProcessTextEditorEvent(workspace_view_text_editor *Editor, platform_event *Event); static void W_BuildTextEditorInfoBar(workspace_view_text_editor *Editor); diff --git a/code/vn_workspace_view.cpp b/code/vn_workspace_view.cpp index e7fbf5e..b58069f 100644 --- a/code/vn_workspace_view.cpp +++ b/code/vn_workspace_view.cpp @@ -1,7 +1,7 @@ //- sixten: Views inline workspace_view *W_CreateNewView(workspace_view_type Type, workspace_panel *Parent) { - memory_arena *Arena = ArenaAllocate(Gigabytes(1)); + arena *Arena = ArenaAlloc(Kilobytes(4), true); workspace_view *View = PushStruct(Arena, workspace_view); View->Arena = Arena; View->Type = Type; @@ -9,16 +9,6 @@ inline workspace_view *W_CreateNewView(workspace_view_type Type, workspace_panel switch(View->Type) { - case W_View_Editor: - { - View->Data = PushStruct(View->Arena, workspace_view_editor); - } break; - - case W_View_CommandPalette: - { - View->Data = PushStruct(View->Arena, workspace_view_command_palette); - } break; - case W_View_Settings: { View->Data = PushStruct(View->Arena, workspace_view_settings); @@ -29,24 +19,21 @@ inline workspace_view *W_CreateNewView(workspace_view_type Type, workspace_panel View->Data = PushStruct(View->Arena, workspace_view_text_editor); workspace_view_text_editor *Editor = (workspace_view_text_editor *)View->Data; - Editor->ProcessingArena = ArenaAllocate(Gigabytes(1)); + Editor->ProcessingArena = ArenaAlloc(Gigabytes(1)); Editor->Text = MutableStringAllocate(Gigabytes(1)); - Editor->HistoryArena = ArenaAllocate(Gigabytes(1)); + Editor->HistoryArena = ArenaAlloc(Gigabytes(1)); SenDLLInit(&Editor->History.Sentinel); Editor->History.At = &Editor->History.Sentinel; Editor->SavePoint = Editor->History.At; + Editor->SelectedItem = -1; + workspace_text_data TextData = W_TextDataFromString(Editor->ProcessingArena, Editor->Text.String); Editor->Tokens = TextData.Tokens; Editor->Lines = TextData.Lines; } break; - case W_View_CharacterEditor: - { - View->Data = PushStruct(View->Arena, workspace_view_character_editor); - } break; - default: break; } @@ -93,7 +80,6 @@ inline string W_GetViewName(workspace_view *View) switch(View->Type) { case W_View_Startup: { Result = StrLit("Welcome"); } break; - case W_View_Editor: { Result = StrLit("Editor"); } break; case W_View_Settings: { Result = StrLit("Settings"); } break; case W_View_TextEditor: { @@ -116,184 +102,12 @@ inline string W_GetViewName(workspace_view *View) } } break; case W_View_SceneView: { Result = StrLit("Scene View"); } break; - case W_View_CommandPalette: { Result = StrLit("Command Palette"); } break; - case W_View_CharacterEditor: { Result = StrLit("Character Editor"); } break; } return(Result); } //- sixten: Builder code -static void W_ViewListerInputCallback(render_group *Group, glyph_atlas *Atlas, ui_box *Box, void *Data) -{ - workspace_view_command_palette *CommandPalette = (workspace_view_command_palette *)Data; - string ToCursor = MakeString(Box->String.Data, CommandPalette->ListerInputEditState.Cursor); - string ToMark = MakeString(Box->String.Data, CommandPalette->ListerInputEditState.Mark); - - r32 TargetCursorX = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, ToCursor); - r32 TargetMarkerX = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, ToMark); - - r32 CursorX = AC_AnimateValueF(TargetCursorX, 0, 0.175, "Workspace View Input Cursor %p", Box); - r32 MarkerX = AC_AnimateValueF(TargetMarkerX, 0, 0.175, "Workspace View Input Mark %p", Box); - - v2 BoxDim = DimOfRange(Box->Rect); - - // sixten: Draw selection - { - v2 Offset = V2(7.5, (BoxDim.y - Box->FontSize) / 2); - v2 Dim = V2(0, Box->FontSize); - if(CursorX > MarkerX) - { - Offset.x += MarkerX; - Dim.x = CursorX - MarkerX; - } - else - { - Offset.x += CursorX; - Dim.x = MarkerX - CursorX; - } - - v2 P = Box->Rect.Min + Offset; - v4 Color = V4(0.4, 0.7, 0.8, 0.3); - PushQuad(Group, Range2R32(P, P+Dim), Color, 0, 0, 0); - } - - // sixten: Draw cursor - if(CommandPalette->ListerFieldSelected) - { - range1_r32 CursorSpan = Range1R32(CursorX, TargetCursorX); - r32 Height = Box->FontSize + 4; - v2 Offset = V2(7.5F + CursorSpan.Min, (BoxDim.y - Height) / 2); - v2 Dim = V2(1.25F + CursorSpan.Max - CursorSpan.Min, Height); - - v2 P = Box->Rect.Min + Offset; - v4 Color = V4(0.3, 1, 0.3, 0.7); - PushQuad(Group, Range2R32(P, P+Dim), Color, 0, 0, 0); - } -} - -static void W_BuildViewTypeLister(workspace_view *View) -{ - workspace_view_command_palette *CommandPalette = (workspace_view_command_palette *)View->Data; - - workspace *Workspace = W_GetState(); - - temporary_memory Scratch = GetScratch(0, 0); - - UI_Size(UI_Percent(1, 1), UI_Percent(1, 1)) - UI_Parent(UI_MakeBox(0, StrLit(""))) - { - UI_Spacer(UI_Pixels(1.25, 1)); - UI_CornerRadius(4) - UI_BackgroundColor(V4(0.5, 0.2, 0.3, 1.0)) - UI_LayoutAxis(Axis2_X) - UI_Height(UI_Pixels(30, 1)) - UI_Parent(UI_MakeBoxF(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawDropShadow, "Workspace View Lister Header")) - { - UI_Spacer(UI_Pixels(5, 1)); - - UI_Width(UI_TextContent(10, 1)) UI_LabelF("Open View:"); - - UI_Spacer(UI_Pixels(15, 1)); - - // sixten: Input Field. - { - r32 SelectedTransition = AC_AnimateValueF(CommandPalette->ListerFieldSelected ? 1.0 : 0.0, - 0, 0.125, "View Input Field %p", View); - - v4 BorderColor = UI_TopBackgroundColor()*2; - BorderColor.w = SelectedTransition; - - UI_SetNextBorderColor(BorderColor); - - UI_SetNextBackgroundColor(LinearBlend(V4(0, 0, 0, 1), UI_TopBackgroundColor(), 0.5)); - UI_SetNextWidth(UI_Percent(1, 0)); - - ui_box *InputBox = UI_MakeBoxF(UI_BoxFlag_DrawBackground | - UI_BoxFlag_Clickable | - UI_BoxFlag_DrawBorder, - "View Type Lister Input"); - - UI_Parent(InputBox) - { - UI_SetNextWidth(UI_TextContent(15, 1)); - - ui_box *InputTextBox = UI_MakeBox(UI_BoxFlag_DrawText, StrLit("Workspace View Lister")); - InputTextBox->String = MakeString(CommandPalette->ListerInput, CommandPalette->ListerInputUsed); - UI_EquipBoxCustomDrawCallback(InputTextBox, W_ViewListerInputCallback, CommandPalette); - } - - UI_Spacer(UI_Pixels(4, 1)); - - if(CommandPalette->ListerFieldSelected) - { - for(platform_event *Event = Workspace->EventList->First; - Event != 0; - Event = Event->Next) - { - if(Event->Type == PlatformEvent_Press || Event->Type == PlatformEvent_Text) - { - text_action Action = SingleLineTextActionFromEvent(Event); - if(IsValid(&Action)) - { - text_op Op = TextOpFromAction(Scratch.Arena, MakeString(CommandPalette->ListerInput, CommandPalette->ListerInputUsed), - &CommandPalette->ListerInputEditState, &Action); - - string Left = MakeString(CommandPalette->ListerInput, Op.Range.Min); - string Right = MakeString(CommandPalette->ListerInput + Op.Range.Max, CommandPalette->ListerInputUsed - Op.Range.Max); - - u64 NewStringSize = Left.Count + Right.Count + Op.ReplaceString.Count; - char *NewString = PushArray(Scratch.Arena, char, NewStringSize); - Copy(NewString, Left.Data, Left.Count); - Copy(NewString + Left.Count, Op.ReplaceString.Data, Op.ReplaceString.Count); - Copy(NewString + Left.Count + Op.ReplaceString.Count, Right.Data, Right.Count); - - CommandPalette->ListerInputUsed = Minimum(ArrayCount(CommandPalette->ListerInput), NewStringSize); - Copy(CommandPalette->ListerInput, NewString, CommandPalette->ListerInputUsed); - - CommandPalette->ListerInputEditState.Cursor = Minimum(Op.NewCursor, CommandPalette->ListerInputUsed); - CommandPalette->ListerInputEditState.Mark = Minimum(Op.NewMark, CommandPalette->ListerInputUsed); - } - } - } - } - - if(UI_SignalFromBox(InputBox).Pressed) - { - CommandPalette->ListerFieldSelected = true; - } - - ui *UI = UI_GetState(); - - if(!(AreEqual(UI->Active, UI_EmptyKey()) || AreEqual(UI->Active, InputBox->Key))) - { - CommandPalette->ListerFieldSelected = false; - } - } - } - - UI_Spacer(UI_Pixels(15, 1)); - - { - UI_SetNextCornerRadius(10); - UI_SetNextBackgroundColor(V4(0.15, 0.15, 0.15, 1.0)); - UI_SetNextBorderColor(V4(0.35, 0.35, 0.35, 1.0)); - UI_SetNextSize(UI_Percent(1, 1), UI_Pixels(100, 1)); - UI_SetNextLayoutAxis(Axis2_Y); - - ui_box *ButtonBox = UI_MakeBox(UI_BoxFlag_DrawBackground | - UI_BoxFlag_DrawBorder | - UI_BoxFlag_HotAnimation | - UI_BoxFlag_ActiveAnimation | - UI_BoxFlag_Clickable, - StrLit("Type Lister Box")); - - UI_SignalFromBox(ButtonBox); - } - } - - ReleaseScratch(Scratch); -} static void W_BuildSettingsTabButton(workspace_view_settings *Settings, char *Name, workspace_settings_category Category) { @@ -442,8 +256,6 @@ static void W_BuildSettings(workspace_view *View) UI_Spacer(UI_Pixels(30, 1)); W_BuildSettingsTabButton(Settings, "General", W_Settings_General); UI_Spacer(UI_Pixels(30, 1)); - W_BuildSettingsTabButton(Settings, "Theme", W_Settings_Theme); - UI_Spacer(UI_Pixels(30, 1)); W_BuildSettingsTabButton(Settings, "Developer", W_Settings_Developer); UI_Spacer(UI_Pixels(150, 1)); @@ -485,34 +297,6 @@ static void W_BuildSettings(workspace_view *View) UI_Spacer(UI_Pixels(50, 1)); } - if(!Category || (Category == W_Settings_Theme)) - { - UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Theme"); - - UI_SetNextSize(UI_Percent(1, 1), UI_Em(13, 1)); - - UI_Scroll(0, &Settings->ThemeScroll) - { - UI_Size(UI_Percent(1, 1), UI_Em(2, 1)) - { - for(s32 Index = 0; - Index < 2; - ++Index) - { - UI_ButtonF("Hello#%i", Index); - UI_ButtonF("Line#%i", Index); - UI_ButtonF("Paint#%i", Index); - UI_ButtonF("Color#%i", Index); - UI_ButtonF("Design#%i", Index); - UI_ButtonF("Address#%i", Index); - UI_ButtonF("Brightness#%i", Index); - } - } - } - - UI_Spacer(UI_Pixels(50, 1)); - } - if(!Category || (Category == W_Settings_Developer)) { UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Developer"); @@ -568,16 +352,6 @@ static void W_BuildView(workspace_view *View) } } break; - case W_View_CommandPalette: - { - W_BuildViewTypeLister(View); - } break; - - case W_View_Editor: - { - Workspace_BuildEditor(View); - } break; - case W_View_Settings: { W_BuildSettings(View); @@ -592,11 +366,6 @@ static void W_BuildView(workspace_view *View) { W_BuildSceneView(View); } break; - - case W_View_CharacterEditor: - { - W_BuildCharacterEditorView(View); - } break; } } diff --git a/code/vn_workspace_view.h b/code/vn_workspace_view.h index 8024740..9a027e5 100644 --- a/code/vn_workspace_view.h +++ b/code/vn_workspace_view.h @@ -8,7 +8,7 @@ struct workspace_view { - memory_arena *Arena; + arena *Arena; enum workspace_view_type Type; workspace_panel *Parent; @@ -21,40 +21,15 @@ struct workspace_view enum workspace_view_type { W_View_Startup, - W_View_Editor, - W_View_CommandPalette, W_View_Settings, W_View_TextEditor, W_View_SceneView, - W_View_CharacterEditor, -}; - -struct workspace_view_editor -{ - v2 Offset; - r32 ZoomLevel; - r32 Scale; // sixten(NOTE): Read-only, based on the zoom level - workspace_editor_node *FirstNode; - workspace_editor_node *LastNode; - workspace_editor_node *FirstFreeNode; - workspace_editor_node *LastFreeNode; - - workspace_editor_lister_dropdown ListerDropdown; -}; - -struct workspace_view_command_palette -{ - b32 ListerFieldSelected; - u8 ListerInput[128]; - s32 ListerInputUsed; - text_edit_state ListerInputEditState; }; enum workspace_settings_category { W_Settings_All, W_Settings_General, - W_Settings_Theme, W_Settings_Developer, }; @@ -65,9 +40,6 @@ struct workspace_view_settings // sixten: General b32 GeneralDropdownOpen; - - // sixten: Theme - r32 ThemeScroll; }; //////////////////////////////// diff --git a/code/win32_main.cpp b/code/win32_main.cpp index 769a2f8..9df75ad 100644 --- a/code/win32_main.cpp +++ b/code/win32_main.cpp @@ -5,6 +5,10 @@ #include "vn_platform.h" +#if W32_LINK_SINGLE +#include "vn.cpp" +#endif + #include "win32_main.h" #include "win32_opengl.cpp" @@ -77,6 +81,17 @@ static PLATFORM_DECOMMIT(Win32_Decommit) VirtualFree(Pointer, Size, MEM_DECOMMIT); } +static PLATFORM_ALLOCATE(Win32_Allocate) +{ + void *Result = VirtualAlloc(0, Size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); + return(Result); +} + +static PLATFORM_DEALLOCATE(Win32_Deallocate) +{ + VirtualFree(Pointer, 0, MEM_DECOMMIT|MEM_RELEASE); +} + static PLATFORM_OPEN_FILE(Win32_OpenFile) { DWORD DesiredAccess = 0; @@ -269,6 +284,7 @@ inline FILETIME Win32_GetLastWriteTime(char *Path) return(Result); } +#if !W32_LINK_SINGLE static win32_loaded_code Win32_LoadCode(void) { win32_loaded_code Code = {}; @@ -317,6 +333,7 @@ static void Win32_UpdateCode(win32_loaded_code *Code) Sleep(500); } } +#endif static PLATFORM_TOGGLE_FULLSCREEN(Win32_ToggleFullscreen) { @@ -558,6 +575,7 @@ static LRESULT Win32_WindowCallback(HWND Window, UINT Message, WPARAM WParam, LP else if(VKCode == VK_END) { Key = Key_End; } else if(VKCode == VK_BACK) { Key = Key_Backspace; } else if(VKCode == VK_DELETE) { Key = Key_Delete; } + else if(VKCode == VK_ESCAPE) { Key = Key_Escape; } if(Key != Key_Invalid) { @@ -744,7 +762,7 @@ int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, i QueryPerformanceFrequency(&FrequencyQuery); State->PerformanceFrequency = FrequencyQuery.QuadPart; - State->EventArena = ArenaAllocate(Gigabytes(1)); + State->EventArena = ArenaAlloc(Gigabytes(1)); State->SleepIsGranular = (timeBeginPeriod(1) == TIMERR_NOERROR); } @@ -759,7 +777,7 @@ int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, i { HWND Window = CreateWindowEx(0, WindowClass.lpszClassName, - "vn - August 2023 Build", + "vn - October 2023 Build", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, @@ -779,7 +797,9 @@ int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, i vn_memory Memory = {}; Memory.PlatformAPI = Platform; +#if !W32_LINK_SINGLE win32_loaded_code LoadedCode = Win32_LoadCode(); +#endif ShowWindow(Window, SW_SHOWNORMAL); @@ -797,14 +817,18 @@ int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, i // sixten: Update and render frame. { + v2_r32 RenderDim = Win32_GetWindowDim(Window); + OpenGL_BeginFrame(&RenderCommands, RenderDim); + +#if W32_LINK_SINGLE + VN_UpdateAndRender(&ThreadContext, &Memory, &Input, &RenderCommands); +#else Win32_UpdateCode(&LoadedCode); - - OpenGL_BeginFrame(&RenderCommands, Win32_GetWindowDim(Window)); - if(LoadedCode.IsValid) { LoadedCode.UpdateAndRender(&ThreadContext, &Memory, &Input, &RenderCommands); } +#endif b32 UseVSync = (Input.RefreshRate == 0); wglSwapIntervalEXT(UseVSync); @@ -831,4 +855,11 @@ int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, i } return(0); -} \ No newline at end of file +} + +#if VN_ASAN_ENABLED +int main(int ArgumentCount, char **Arguments) +{ + return WinMain(GetModuleHandle(0), 0, 0, 0); +} +#endif \ No newline at end of file diff --git a/code/win32_main.h b/code/win32_main.h index 2b62b1f..cabefb6 100644 --- a/code/win32_main.h +++ b/code/win32_main.h @@ -10,7 +10,7 @@ struct win32_state HWND Window; - memory_arena *EventArena; + arena *EventArena; platform_event_list EventList; char EXEPath[512]; diff --git a/config.vn b/config.vn index 05d0675..e6e6e3f 100644 --- a/config.vn +++ b/config.vn @@ -1,6 +1,6 @@ Platform { - RefreshRate = 60; + RefreshRate = 144; } Dev diff --git a/data/backgrounds/ddlc-club.png b/data/backgrounds/ddlc-club.png new file mode 100644 index 0000000..c340d4c Binary files /dev/null and b/data/backgrounds/ddlc-club.png differ diff --git a/data/characters/monika_leaning.png b/data/characters/monika_leaning.png new file mode 100644 index 0000000..0ec44d7 Binary files /dev/null and b/data/characters/monika_leaning.png differ diff --git a/data/ddlc.vns b/data/ddlc.vns index 9e6a975..686ba0a 100644 --- a/data/ddlc.vns +++ b/data/ddlc.vns @@ -6,4 +6,6 @@ proc main "We used to walk to school together on days like this, but starting around high school she would oversleep more and more frequently, and I would get tired of waiting up."; "But if she's going to chase after me like this, I almost feel better off running away."; "However, I just sigh and idle in front of the crosswalk and let Sayori catch up to me."; + + jump main; } \ No newline at end of file diff --git a/data/ddlc2.vns b/data/ddlc2.vns new file mode 100644 index 0000000..f0debb4 --- /dev/null +++ b/data/ddlc2.vns @@ -0,0 +1,30 @@ +var monika = "Monika"; +var arthur = "Arthur"; + +proc main +{ + "hello, line, paint, color, design, address, brightness"; + + @monika(leaning) "Hi"; + + @arthur(normal) "Wasssap!"; + + @monika(leaning) "This is completely normal"; + + @monika(none); + + @arthur(normal) "Wow, what a rude person"; + @arthur(happy) "But hey! They left atleast!"; + + @arthur(none); + + "Something inbetween!"; + + @monika(leaning) @arthur(happy) "BOOOO!"; + + "Gotcha'!"; + + @arthur(none) @monika(none); + + jump main; +} \ No newline at end of file diff --git a/fonts/DejaVuSansMono-Bold.ttf b/data/fonts/DejaVuSansMono-Bold.ttf similarity index 100% rename from fonts/DejaVuSansMono-Bold.ttf rename to data/fonts/DejaVuSansMono-Bold.ttf diff --git a/fonts/DejaVuSansMono-Oblique.ttf b/data/fonts/DejaVuSansMono-Oblique.ttf similarity index 100% rename from fonts/DejaVuSansMono-Oblique.ttf rename to data/fonts/DejaVuSansMono-Oblique.ttf diff --git a/fonts/DejaVuSansMono.ttf b/data/fonts/DejaVuSansMono.ttf similarity index 100% rename from fonts/DejaVuSansMono.ttf rename to data/fonts/DejaVuSansMono.ttf diff --git a/fonts/Merriweather-Regular.ttf b/data/fonts/Merriweather-Regular.ttf similarity index 100% rename from fonts/Merriweather-Regular.ttf rename to data/fonts/Merriweather-Regular.ttf diff --git a/fonts/NotoSansJP-Regular.ttf b/data/fonts/NotoSansJP-Regular.ttf similarity index 100% rename from fonts/NotoSansJP-Regular.ttf rename to data/fonts/NotoSansJP-Regular.ttf diff --git a/fonts/PatrickHand-Regular.ttf b/data/fonts/PatrickHand-Regular.ttf similarity index 100% rename from fonts/PatrickHand-Regular.ttf rename to data/fonts/PatrickHand-Regular.ttf diff --git a/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf similarity index 100% rename from fonts/Roboto-Bold.ttf rename to data/fonts/Roboto-Bold.ttf diff --git a/fonts/Roboto-Regular.ttf b/data/fonts/Roboto-Regular.ttf similarity index 100% rename from fonts/Roboto-Regular.ttf rename to data/fonts/Roboto-Regular.ttf diff --git a/fonts/icons.ttf b/data/fonts/icons.ttf similarity index 100% rename from fonts/icons.ttf rename to data/fonts/icons.ttf diff --git a/fonts/liberation-mono.ttf b/data/fonts/liberation-mono.ttf similarity index 100% rename from fonts/liberation-mono.ttf rename to data/fonts/liberation-mono.ttf diff --git a/data/scene.vns b/data/scene.vns new file mode 100644 index 0000000..009557e --- /dev/null +++ b/data/scene.vns @@ -0,0 +1,23 @@ +var arthur = "Arthur"; +var monika = "Monika"; + +proc main +{ + @arthur(normal) "Welcome to the Scene Test!"; + @arthur(happy) "Feel free to move around."; + + branch + { + "No! Sooth me with your voice one more time." + { + @monika(leaning) "Really? Him?!?!"; + @monika(leaning) "If you say so..."; + @monika(none); + jump main; + } + "Okay!" + { + @arthur(none); + } + } +} \ No newline at end of file diff --git a/project.4coder b/project.4coder index c215f73..1c05700 100644 --- a/project.4coder +++ b/project.4coder @@ -32,14 +32,14 @@ load_paths = command_list = { { - .name = "build", + .name = "build-win32", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, .cmd = { - { "build.bat", .os = "win" }, + { "code\\build.bat", .os = "win" }, }, }, @@ -67,7 +67,21 @@ command_list = }, }, + { + .name = "build-wasm", + .out = "*compilation*", + .footer_panel = true, + .save_dirty_files = true, + .cursor_at_end = false, + .cmd = + { + { "code\\build_emscripten.bat", .os = "win" }, + }, + }, + }; +fkey_command[1] = "build-win32"; fkey_command[2] = "run"; fkey_command[3] = "cloc"; +fkey_command[4] = "build-wasm"; diff --git a/weeks.txt b/weeks.txt index 8f14a1d..2c2d0df 100644 --- a/weeks.txt +++ b/weeks.txt @@ -1,6 +1,18 @@ [0] - Characters + - Get characters names displaying while they talk V +//////////////////////////////// + [1] - Environments & Time + [2] - Map & Notebook + [3] - UI + - Keyboard Navigation + - Blinking Caret + [4] - Minigames -[5] - Rendering \ No newline at end of file + +[5] - Rendering + - Check up on texture mappings, something seems to be weird + +[6] - Data Submission \ No newline at end of file