parent
6e93783b03
commit
b50ab896bb
|
@ -1 +1,2 @@
|
|||
build/
|
||||
release/
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -42,32 +42,99 @@ static void Fill(void *Dest, u8 Value, umm Count)
|
|||
}
|
||||
}
|
||||
|
||||
#if VN_ASAN_ENABLED
|
||||
#include <sanitizer/asan_interface.h>
|
||||
#endif
|
||||
|
||||
////////////////////////////////
|
||||
//- sixten: Memory Arena Functions
|
||||
|
||||
static memory_arena *ArenaAllocate(u64 Size)
|
||||
static arena *ArenaAlloc(u64 Size, b32 Chaining)
|
||||
{
|
||||
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);
|
||||
memory_arena *Arena = (memory_arena *)Memory;
|
||||
Arena->Position = sizeof(memory_arena);
|
||||
Arena->CommitPosition = 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)
|
||||
{
|
||||
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->Chaining)
|
||||
{
|
||||
if(Size <= Arena->Size)
|
||||
{
|
||||
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
|
||||
{
|
||||
if(Arena->Position + Size <= Arena->Size)
|
||||
{
|
||||
u8 *Base = (u8 *)Arena;
|
||||
|
@ -89,18 +156,52 @@ static void *ArenaPushNoClear(memory_arena *Arena, u64 Size)
|
|||
{
|
||||
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)
|
||||
{
|
||||
if(Arena->Chaining)
|
||||
{
|
||||
// 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;
|
||||
|
@ -113,19 +214,20 @@ static void ArenaPopTo(memory_arena *Arena, u64 Position)
|
|||
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,5 +4,6 @@ CR_State_Invalid = 0,
|
|||
CR_State_None,
|
||||
CR_State_Normal,
|
||||
CR_State_Happy,
|
||||
CR_State_Leaning,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;\
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
43
code/vn.cpp
43
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
|
||||
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -30,7 +30,7 @@ struct animation_curve_bucket
|
|||
|
||||
struct animation_curve_state
|
||||
{
|
||||
memory_arena *Arena;
|
||||
arena *Arena;
|
||||
|
||||
u32 CurrentFrame;
|
||||
r32 dtForFrame;
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -3,6 +3,7 @@
|
|||
{ "none", None },
|
||||
{ "normal", Normal },
|
||||
{ "happy", Happy },
|
||||
{ "leaning", Leaning },
|
||||
}
|
||||
|
||||
@table_gen
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {};
|
||||
|
||||
|
|
|
@ -95,6 +95,8 @@ enum platform_key
|
|||
|
||||
Key_Backspace, Key_Delete,
|
||||
|
||||
Key_Escape,
|
||||
|
||||
Key_MouseLeft, Key_MouseMiddle, Key_MouseRight,
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
109
code/vn_scene.h
109
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
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
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, CharsRevealed, Box->Rect.Min+Offset, DimOfRange(Box->Rect).x-2*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,8 +270,11 @@ static void BuildScene(scene_view *View)
|
|||
ui_box *Box = UI_MakeBox(0, StrLit("Scene View"));
|
||||
UI_EquipBoxCustomDrawCallback(Box, BuildSceneDrawCallback, View);
|
||||
|
||||
if(SV_CurrentlyInProc())
|
||||
{
|
||||
UI_Parent(Box)
|
||||
{
|
||||
//- sixten: build branches
|
||||
UI_WidthFill UI_Height(UI_Percent(1, 0)) UI_Row() UI_FillPadding UI_Column() UI_FillPadding
|
||||
{
|
||||
b32 FoundOffset = false;
|
||||
|
@ -219,14 +295,24 @@ static void BuildScene(scene_view *View)
|
|||
}
|
||||
}
|
||||
|
||||
UI_SetNextWidth(UI_Percent(1, 1));
|
||||
UI_SetNextHeight(UI_Percent(0.3, 1));
|
||||
//- sixten: build textbox
|
||||
UI_Size(UI_Percent(1, 1), 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;
|
||||
TextboxData->Name = View->LastTalkingCharacter;
|
||||
TextboxData->NameT = View->CharacterIsTalkingT;
|
||||
UI_EquipBoxCustomDrawCallback(TextBox, BuildSceneTextboxDrawCallback, TextboxData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//- sixten: render environmental objects
|
||||
}
|
||||
}
|
||||
|
||||
static void BuildErrorScreen(scene_runtime *Runtime, vn_input *Input)
|
||||
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
Workspace->Menu = W_ToolbarMenu_None;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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,7 +477,8 @@ 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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -480,15 +487,21 @@ static workspace_text_editor_lister_action W_BuildTextEditorLister(workspace_vie
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- sixten: build navbar
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
|
@ -832,3 +856,10 @@ int WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, i
|
|||
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if VN_ASAN_ENABLED
|
||||
int main(int ArgumentCount, char **Arguments)
|
||||
{
|
||||
return WinMain(GetModuleHandle(0), 0, 0, 0);
|
||||
}
|
||||
#endif
|
|
@ -10,7 +10,7 @@ struct win32_state
|
|||
|
||||
HWND Window;
|
||||
|
||||
memory_arena *EventArena;
|
||||
arena *EventArena;
|
||||
platform_event_list EventList;
|
||||
|
||||
char EXEPath[512];
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
Binary file not shown.
After Width: | Height: | Size: 438 KiB |
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
|
|
12
weeks.txt
12
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
|
||||
- Check up on texture mappings, something seems to be weird
|
||||
|
||||
[6] - Data Submission
|
Loading…
Reference in New Issue