From 41c1f17158795570455aaf9912286e2a75cac69f Mon Sep 17 00:00:00 2001 From: sixtenhugosson Date: Tue, 5 Sep 2023 19:50:49 +0200 Subject: [PATCH] Started work on the character editor. --- code/build.bat | 4 +- code/opengl_render.cpp | 8 +- code/vn.cpp | 12 + code/vn_character.cpp | 51 ++++ code/vn_character.h | 38 +++ code/vn_scene.cpp | 402 ++++++++++++------------- code/vn_scene.h | 42 ++- code/vn_scene_view.cpp | 6 +- code/vn_tokenizer.cpp | 1 + code/vn_tokenizer.h | 1 + code/vn_ui_utils.cpp | 4 +- code/vn_workspace.cpp | 18 +- code/vn_workspace.h | 1 + code/vn_workspace_character_editor.cpp | 100 ++++++ code/vn_workspace_character_editor.h | 40 +++ code/vn_workspace_view.cpp | 92 +++--- code/vn_workspace_view.h | 1 + code/win32__main.rdbg | Bin 1026 -> 1073 bytes data/demo.vns | 11 + test | 31 ++ 20 files changed, 597 insertions(+), 266 deletions(-) create mode 100644 code/vn_character.cpp create mode 100644 code/vn_character.h create mode 100644 code/vn_workspace_character_editor.cpp create mode 100644 code/vn_workspace_character_editor.h create mode 100644 data/demo.vns create mode 100644 test diff --git a/code/build.bat b/code/build.bat index 3fdafea..4e531b8 100644 --- a/code/build.bat +++ b/code/build.bat @@ -1,11 +1,11 @@ @echo off -set CommonCompilerOptions=/Zi /FC /nologo /DVN_INTERNAL=1 /DVN_SLOW=1 /DVN_USE_INSTANCING=1 /Oi /W4 /WX /wd4996 /wd4201 /wd4305 /wd4244 /wd4100 /wd4505 /std:c++17 +set CommonCompilerOptions=/Zi /FC /nologo /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/" -cl /Zi /nologo /FC ../code/third_party/codegen/codegen.c +rem cl /Zi /nologo /FC ../code/third_party/codegen/codegen.c codegen ../code/ cl %CommonCompilerOptions% ../code/vn.cpp /LD /link /export:VN_UpdateAndRender /incremental:no diff --git a/code/opengl_render.cpp b/code/opengl_render.cpp index 5367a9f..9931503 100644 --- a/code/opengl_render.cpp +++ b/code/opengl_render.cpp @@ -385,12 +385,11 @@ void main() { v2[] Vertices = V2[](V2(0, 0), V2(0, 1), V2(1, 0), V2(1, 1)); -DestP = In_Dest.xy + (In_Dest.zw-In_Dest.xy)*Vertices[gl_VertexID]; +DestP = LinearBlend(In_Dest.xy, In_Dest.zw, Vertices[gl_VertexID]); DestHalfSize = (In_Dest.zw-In_Dest.xy)/2; DestCenter = (In_Dest.xy+In_Dest.zw)/2; -v2 SourceDim = In_Source.zw-In_Source.xy; -SourceP = In_Source.xy + SourceDim*Vertices[gl_VertexID]; +SourceP = LinearBlend(In_Source.xy, In_Source.zw, Vertices[gl_VertexID]); v2 ScreenP = V2(DestP.x / Uniform_Resolution.x, DestP.y / Uniform_Resolution.y); ScreenP = ScreenP*2 - 1; @@ -448,8 +447,9 @@ r32 BorderFactor = 1; if(BorderThickness != 0) { v2 InteriorHalfSize = DestHalfSize - BorderThickness; +v2 InteriorRadiusReducePair = InteriorHalfSize / DestHalfSize; -r32 InteriorRadiusReduce = Min(InteriorHalfSize.x / DestHalfSize.x, InteriorHalfSize.y / DestHalfSize.y); +r32 InteriorRadiusReduce = Min(InteriorRadiusReducePair.x, InteriorRadiusReducePair.y); r32 InteriorCornerRadius = CornerRadius*InteriorRadiusReduce*InteriorRadiusReduce; r32 InsideDist = RoundedRect(DestP, DestCenter, InteriorHalfSize - SoftnessPadding, InteriorCornerRadius); diff --git a/code/vn.cpp b/code/vn.cpp index 9872f07..861f1d1 100644 --- a/code/vn.cpp +++ b/code/vn.cpp @@ -27,6 +27,7 @@ global debug_settings *DEBUG_DebugSettings = 0; #include "vn_workspace.h" #include "vn_animation_curve.h" #include "vn_theme_dark.h" +#include "vn_character.h" #include "vn_tokenizer.cpp" #include "vn_config.cpp" @@ -38,6 +39,7 @@ global debug_settings *DEBUG_DebugSettings = 0; #include "vn_scene.cpp" #include "vn_scene_view.cpp" #include "vn_workspace.cpp" +#include "vn_character.cpp" struct vn_state { @@ -52,6 +54,7 @@ struct vn_state workspace Workspace; animation_curve_state AnimationCurveState; + character_registry CharacterRegistry; render_handle BackgroundTexture; scene_view SceneView; @@ -136,6 +139,15 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender) SV_Init(SceneView, State->Arena); SceneView->BackgroundTexture = State->BackgroundTexture; + //- sixten: create mock characters + CR_Init(&State->CharacterRegistry); + character_entry *Arthur = CR_EntryFromName(StrLit("Arthur")); + UnusedVariable(Arthur); + + CR_EntryFromName(StrLit("Catherine")); + CR_EntryFromName(StrLit("Quinn")); + CR_EntryFromName(StrLit("Margaret")); + UI_Init(&State->UI); W_Init(&State->Workspace); AC_Init(&State->AnimationCurveState); diff --git a/code/vn_character.cpp b/code/vn_character.cpp new file mode 100644 index 0000000..1d6a68e --- /dev/null +++ b/code/vn_character.cpp @@ -0,0 +1,51 @@ +global character_registry *Global_CharacterRegistry = 0; + +//////////////////////////////// +//~ 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) +{ + character_registry *Registry = CR_GetState(); + character_list List = Registry->Characters; + return(List); +} + +static void CR_Init(character_registry *State) +{ + CR_SetState(State); + + State->Arena = ArenaAllocate(Megabytes(32)); +} + +static character_entry *CR_EntryFromName(string Name) +{ + character_entry *Entry = 0; + + character_registry *Registry = CR_GetState(); + for(character_entry *Iter = Registry->Characters.First; Iter != 0; Iter = Iter->Next) + { + if(AreEqual(Name, Iter->Name)) + { + Entry = Iter; + break; + } + } + + if(!Entry) + { + Entry = PushStruct(Registry->Arena, character_entry); + Entry->Name = PushString(Registry->Arena, Name); + DLLInsertLast(Registry->Characters.First, Registry->Characters.Last, Entry); + } + + return(Entry); +} \ No newline at end of file diff --git a/code/vn_character.h b/code/vn_character.h new file mode 100644 index 0000000..b1d315c --- /dev/null +++ b/code/vn_character.h @@ -0,0 +1,38 @@ +/* date = August 30th 2023 6:28 pm */ + +#ifndef VN_CHARACTER_H +#define VN_CHARACTER_H + +//////////////////////////////// +//~ 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; +}; + + +//////////////////////////////// +//~ 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); + +#endif //VN_CHARACTER_H diff --git a/code/vn_scene.cpp b/code/vn_scene.cpp index 0d6cf68..6361287 100644 --- a/code/vn_scene.cpp +++ b/code/vn_scene.cpp @@ -6,13 +6,16 @@ static void S_ParseError(scene_compiler *Compiler, char *Message, s64 TokenOffset) { - Compiler->EncounteredError = true; - Compiler->InPanicMode = true; - scene_compile_error *Error = PushStruct(Compiler->Arena, scene_compile_error); - Error->Message = PushFormat(Compiler->Arena, Message); - Error->Token = Compiler->At[TokenOffset]; - QueuePush(Compiler->Errors.First, Compiler->Errors.Last, Error); - Compiler->Errors.Count += 1; + if(!Compiler->InPanicMode) + { + Compiler->EncounteredError = true; + Compiler->InPanicMode = true; + scene_compile_error *Error = PushStruct(Compiler->Arena, scene_compile_error); + Error->Message = PushFormat(Compiler->Arena, Message); + Error->Token = Compiler->At[TokenOffset]; + QueuePush(Compiler->Errors.First, Compiler->Errors.Last, Error); + Compiler->Errors.Count += 1; + } } static void S_EmitByte(scene_compiler *Compiler, u8 Byte) @@ -32,6 +35,14 @@ static void S_EmitByte(scene_compiler *Compiler, u8 Byte) Chunk->Count += 1; } +static void S_EmitU32(scene_compiler *Compiler, u32 Value) +{ + S_EmitByte(Compiler, Value >> 0); + S_EmitByte(Compiler, Value >> 8); + S_EmitByte(Compiler, Value >> 16); + S_EmitByte(Compiler, Value >> 24); +} + static void S_EmitBucket(scene_compiler *Compiler, scene_annotated_bytecode_bucket *Bucket) { for(scene_annotated_bytecode_chunk *Chunk = Bucket->First; Chunk != 0; Chunk = Chunk->Next) @@ -51,44 +62,17 @@ static u64 S_MakeConstant(scene_compiler *Compiler, scene_value Value) Chunk = PushStruct(Compiler->Arena, scene_value_chunk); QueuePush(Compiler->FirstValueChunk, Compiler->LastValueChunk, Chunk); } - Chunk->Values[Chunk->Count] = Value; u64 Result = Compiler->ValueCount; - Compiler->ValueCount += 1; + Chunk->Values[Chunk->Count] = Value; Chunk->Count += 1; - return(Result); -} - -static s64 S_EmitVariableLength(scene_compiler *Compiler, u64 Value) -{ - s64 Length = 1; - u64 Index = Value; - for(;Index > 0x7F; Index >>= 7) - { - S_EmitByte(Compiler, Index|0x80); - Length += 1; - InvalidCodepath; - } - S_EmitByte(Compiler, Index); - return(Length); -} - -static scene_variable_read S_ReadVariableLength(u8 *Byte) -{ - scene_variable_read Result = {}; - u8 *StartByte = Byte; - for(;*Byte & 0x80; Byte += 1) - { - Result.Value = (Result.Value<<7)|(*Byte & 0x7F); - } - Result.Value = (Result.Value<<7)|(*Byte & 0x7F); - Result.Size = Byte-StartByte+1; + Compiler->ValueCount += 1; return(Result); } static void S_EmitConstant(scene_compiler *Compiler, scene_value Value) { S_EmitByte(Compiler, S_Op_Constant); - S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, Value)); + S_EmitU32(Compiler, S_MakeConstant(Compiler, Value)); } static void S_SetEmissionTarget(scene_compiler *Compiler, scene_emission_target Target) @@ -148,6 +132,7 @@ static scene_parse_rule S_ParseRuleFromToken(scene_compiler *Compiler, token Tok case TokenKind_False: { Result = { S_ParseLiteral, 0, S_Precedence_None }; } break; case TokenKind_True: { Result = { S_ParseLiteral, 0, S_Precedence_None }; } break; case TokenKind_Numeric: { Result = { S_ParseNumber, 0, S_Precedence_None }; } break; + case TokenKind_StringLiteral: { Result = { S_ParseString, 0, S_Precedence_None }; } break; case TokenKind_Identifier: { Result = { S_ParseVariable, 0, S_Precedence_None }; } break; default: { @@ -235,11 +220,6 @@ static void S_ParseDeclaration(scene_compiler *Compiler) Compiler->At += 1; S_ParseVariableDeclaration(Compiler); } break; - case TokenKind_StringLiteral: - { - Compiler->At += 1; - S_ParseLineEntry(Compiler); - } break; case TokenKind_Jump: { Compiler->At += 1; @@ -250,9 +230,46 @@ static void S_ParseDeclaration(scene_compiler *Compiler) Compiler->At += 1; S_ParseBranchStatement(Compiler); } break; + case TokenKind_StringLiteral: + { + S_ParseExpression(Compiler); + S_EmitByte(Compiler, S_Op_LineEntry); + + //- sixten: parse tags + { + b32 EmitAwait = true; + scene_line_entry_flag Flags = 0; + for(;Compiler->At[0].Kind == TokenKind_PoundSign;) + { + Compiler->At += 1; + token TagToken = S_ConsumeToken(Compiler, TokenKind_Identifier, "Expected tag name after '#'."); + string TagString = T_StringFromToken(Compiler->Text, TagToken); + if(AreEqual(TagString, StrLit("noclear"))) + { + Flags |= S_LineEntryFlag_NoClear; + } + else if(AreEqual(TagString, StrLit("noawait"))) + { + EmitAwait = false; + } + else + { + S_ParseError(Compiler, "Unknown tag."); + } + } + + if(EmitAwait) + { + S_EmitByte(Compiler, S_Op_AwaitInput); + } + + S_ConsumeToken(Compiler, TokenKind_Semicolon, "Expected ';' after statement."); + } + } break; default: { S_ParseStatement(Compiler); + S_EmitByte(Compiler, S_Op_Pop); } break; } @@ -260,17 +277,18 @@ static void S_ParseDeclaration(scene_compiler *Compiler) { for(;Compiler->At < Compiler->TokensEnd;) { - if(Compiler->At[0].Kind == TokenKind_Semicolon) + if(Compiler->At[-1].Kind == TokenKind_Semicolon) { goto End; } - switch(Compiler->At[-1].Kind) + switch(Compiler->At[0].Kind) { case TokenKind_Var: goto End; case TokenKind_StringLiteral: goto End; case TokenKind_Jump: goto End; case TokenKind_Branch: goto End; + default: break; } Compiler->At += 1; @@ -299,13 +317,9 @@ static void S_ParseVariableDeclaration(scene_compiler *Compiler) S_ConsumeToken(Compiler, TokenKind_Semicolon, "Expected ';' after variable declaration."); S_EmitByte(Compiler, S_Op_DefineGlobal); - u64 Index = NameConstant; - for(;Index > 0x7F; Index >>= 7) - { - S_EmitByte(Compiler, Index|0x80); - InvalidCodepath; - } - S_EmitByte(Compiler, Index); + + Assert(NameConstant < U32_Max); + S_EmitU32(Compiler, NameConstant); } static void S_ParseVariable(scene_compiler *Compiler, b32 CanAssign) @@ -326,44 +340,7 @@ static void S_ParseNamedVariable(scene_compiler *Compiler, token Token, b32 CanA { S_EmitByte(Compiler, S_Op_GetGlobal); } - S_EmitVariableLength(Compiler, NameConstant); -} - -static void S_ParseLineEntry(scene_compiler *Compiler) -{ - token LineToken = Compiler->At[-1]; - - b32 EmitAwait = true; - - // sixten: tags -> flags - scene_line_entry_flag Flags = 0; - for(;Compiler->At[0].Kind == TokenKind_PoundSign;) - { - Compiler->At += 1; - token TagToken = S_ConsumeToken(Compiler, TokenKind_Identifier, "Expected tag name after '#'."); - string TagString = T_StringFromToken(Compiler->Text, TagToken); - if(AreEqual(TagString, StrLit("noclear"))) - { - Flags |= S_LineEntryFlag_NoClear; - } - else if(AreEqual(TagString, StrLit("noawait"))) - { - EmitAwait = false; - } - else - { - S_ParseError(Compiler, "Unknown tag."); - } - } - - S_ConsumeToken(Compiler, TokenKind_Semicolon, "Expected ';' after line entry."); - - S_EmitByte(Compiler, S_Op_LineEntry|Flags); - S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(LineToken))); - if(EmitAwait) - { - S_EmitByte(Compiler, S_Op_AwaitInput); - } + S_EmitU32(Compiler, NameConstant); } static void S_ParseJumpStatement(scene_compiler *Compiler) @@ -372,7 +349,7 @@ static void S_ParseJumpStatement(scene_compiler *Compiler) token DestToken = Compiler->At[-1]; S_EmitByte(Compiler, S_Op_Jump); - S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(DestToken))); + S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(DestToken))); S_ConsumeToken(Compiler, TokenKind_Semicolon, "Expected ';' after jump statement."); } @@ -415,8 +392,8 @@ static void S_ParseBranchStatement(scene_compiler *Compiler) for(scene_branch_case *Branch = FirstBranch; Branch != 0; Branch = Branch->Next) { S_EmitByte(Compiler, S_Op_AddBranch); - S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(Branch->Name))); - S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeOffset(0))); + S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(Branch->Name))); + S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeOffset(0))); scene_value_chunk *Chunk = Compiler->LastValueChunk; Branch->OffsetValue = &Chunk->Values[Chunk->Count-1]; } @@ -441,8 +418,8 @@ static void S_ParseBranchStatement(scene_compiler *Compiler) S_EmitByte(Compiler, S_Op_JumpClose); BaseOffset += 1; - - BaseOffset += S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeOffset(BaseOffset))); + S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeOffset(BaseOffset))); + BaseOffset += 4; scene_value_chunk *Chunk = Compiler->LastValueChunk; Branch->EndOffsetValue = &Chunk->Values[Chunk->Count-1]; @@ -451,7 +428,8 @@ static void S_ParseBranchStatement(scene_compiler *Compiler) //- sixten: patch the last jump for(scene_branch_case *Branch = FirstBranch; Branch != 0; Branch = Branch->Next) { - Branch->EndOffsetValue->Offset = BaseOffset-Branch->EndOffsetValue->Offset; + // sixten(NOTE): This little line here feels rather sketchy, it may one day fail on us. + Branch->EndOffsetValue->Offset = BaseOffset-Branch->EndOffsetValue->Offset-4; } ReleaseScratch(Scratch); @@ -511,6 +489,11 @@ static void S_ParseNumber(scene_compiler *Compiler, b32 CanAssign) S_EmitConstant(Compiler, S_MakeNumber(Value)); } +static void S_ParseString(scene_compiler *Compiler, b32 CanAssign) +{ + S_EmitConstant(Compiler, S_MakeSourceRef(Compiler->At[-1])); +} + static void S_ParseGrouping(scene_compiler *Compiler, b32 CanAssign) { S_ParseExpression(Compiler); @@ -581,105 +564,6 @@ static void S_ParsePrecedence(scene_compiler *Compiler, scene_precedence Precede } } -static string S_DisassembleBytecode(scene_compiler *Compiler, scene_annotated_bytecode_chunk *Chunk, memory_arena *Arena) -{ - string_list List = {}; - - temporary_memory Scratch = GetScratch(&Arena, 1); - - u8 *ChunkBegin = Chunk->Data; - u8 *ChunkEnd = ChunkBegin + Chunk->Count; - for(u8 *Data = ChunkBegin; Data < ChunkEnd;) - { - switch(*Data) - { - case S_Op_Constant: - { - Data += 1; - scene_variable_read VariableRead = S_ReadVariableLength(Data); - Data += VariableRead.Size; - scene_value Value = Compiler->FirstValueChunk->Values[VariableRead.Value]; - AppendString(&List, StrLit("Constant: "), Scratch.Arena); - switch(Value.Kind) - { - case S_ValueKind_Number: { AppendString(&List, PushFormat(Scratch.Arena, "%f (number)\n", Value.Number), Scratch.Arena); } break; - case S_ValueKind_Boolean: { AppendString(&List, PushFormat(Scratch.Arena, "%b (boolean)\n", Value.Boolean), Scratch.Arena); } break; - case S_ValueKind_Pointer: { AppendString(&List, PushFormat(Scratch.Arena, "%x (pointer)\n", Value.Pointer), Scratch.Arena); } break; - } - } break; - case S_Op_Nil: { AppendString(&List, StrLit("Nil\n"), Scratch.Arena); Data += 1; } break; - case S_Op_True: { AppendString(&List, StrLit("True\n"), Scratch.Arena); Data += 1; } break; - case S_Op_False: { AppendString(&List, StrLit("False\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Negate: { AppendString(&List, StrLit("Negate\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Not: { AppendString(&List, StrLit("Not\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Add: { AppendString(&List, StrLit("Add\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Subtract: { AppendString(&List, StrLit("Subtract\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Multiply: { AppendString(&List, StrLit("Multiply\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Divide: { AppendString(&List, StrLit("Divide\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Equal: { AppendString(&List, StrLit("Equal\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Greater: { AppendString(&List, StrLit("Greater\n"), Scratch.Arena); Data += 1; } break; - case S_Op_Less: { AppendString(&List, StrLit("Less\n"), Scratch.Arena); Data += 1; } break; - case S_Op_DefineGlobal: - { - Data += 1; - scene_variable_read VariableRead = S_ReadVariableLength(Data); - Data += VariableRead.Size; - u64 Pointer = Compiler->FirstValueChunk->Values[VariableRead.Value].Pointer; - token *Token = (token *)Pointer; - string String = T_StringFromToken(Compiler->Text, *Token); - AppendString(&List, StrLit("Define Global: "), Scratch.Arena); - AppendString(&List, String, Scratch.Arena); - AppendString(&List, StrLit("\n"), Scratch.Arena); - } break; - - case S_Op_GetGlobal: - { - Data += 1; - scene_variable_read VariableRead = S_ReadVariableLength(Data); - Data += VariableRead.Size; - u64 Pointer = Compiler->FirstValueChunk->Values[VariableRead.Value].Pointer; - token *Token = (token *)Pointer; - string String = T_StringFromToken(Compiler->Text, *Token); - AppendString(&List, PushFormat(Scratch.Arena, "Get Global: %S\n", String), Scratch.Arena); - } break; - case S_Op_SetGlobal: - { - Data += 1; - scene_variable_read VariableRead = S_ReadVariableLength(Data); - Data += VariableRead.Size; - u64 Pointer = Compiler->FirstValueChunk->Values[VariableRead.Value].Pointer; - token *Token = (token *)Pointer; - string String = T_StringFromToken(Compiler->Text, *Token); - AppendString(&List, PushFormat(Scratch.Arena, "Set Global: %S\n", String), Scratch.Arena); - } break; - case S_Op_AwaitInput: { AppendString(&List, StrLit("Await Input\n"), Scratch.Arena); } break; - default: - { - if(*Data & S_Op_LineEntry) - { - Data += 1; - scene_variable_read VariableRead = S_ReadVariableLength(Data); - Data += VariableRead.Size; - u64 Pointer = Compiler->FirstValueChunk->Values[VariableRead.Value].Pointer; - token *Token = (token *)Pointer; - string String = Substring(Compiler->Text, Pad(Token->Range, -1)); - AppendString(&List, PushFormat(Scratch.Arena, "Line Entry: %S\n", String), Scratch.Arena); - } - else - { - AppendString(&List, StrLit("Unknown Op\n"), Scratch.Arena); - Data += 1; - } - } break; - } - } - - string Result = JoinStringList(&List, Arena); - - ReleaseScratch(Scratch); - return(Result); -} - struct proc_from_chunks_result { scene_proc *Proc; @@ -696,11 +580,11 @@ static proc_from_chunks_result S_ProcFromChunks(memory_arena *Arena, scene_annot scene_annotated_bytecode_chunk *NextChunk = 0; { scene_annotated_bytecode_chunk *Chunk = First; - for(; Chunk != 0 && AreEqual(Chunk->Name, ChunkName); Chunk = Chunk->Next) + for(;Chunk != 0 && AreEqual(Chunk->Name, ChunkName); Chunk = Chunk->Next) { RequiredBytes += Chunk->Count; } - NextChunk= Chunk; + NextChunk = Chunk; } scene_proc *Proc = PushStruct(Arena, scene_proc); @@ -838,7 +722,7 @@ static compiled_scene S_CopyCompiledScene(memory_arena *Arena, compiled_scene *C //- sixten: copy the source Result.Source = PushString(Arena, Compiled->Source); - Result.IsValid = true;//Compiled->IsValid; + Result.IsValid = true;//Compiled->IsValid; sixten(TODO): I don't know why this is commented out. return(Result); } @@ -880,6 +764,36 @@ static scene_proc *S_FindProcByName(compiled_scene *Compiled, string Name) return(Result); } +static void S_PushStack(scene_runtime *Runtime, scene_value Value) +{ + scene_runtime_stack *Stack = &Runtime->Stack; + if(Stack->Count < ArrayCount(Stack->Stack)) + { + Stack->Stack[Stack->Count] = Value; + Stack->Count += 1; + } + else + { + S_RuntimeError(Runtime, StrLit("Stack overflow")); + } +} + +static scene_value S_PopStack(scene_runtime *Runtime) +{ + scene_value Result = {}; + scene_runtime_stack *Stack = &Runtime->Stack; + if(Stack->Count > 0) + { + Stack->Count -= 1; + Result = Stack->Stack[Stack->Count]; + } + else + { + S_RuntimeError(Runtime, StrLit("Stack underflow")); + } + return(Result); +} + static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameArena, b32 AdvanceOnAwait) { scene_runtime_result Result = {}; @@ -893,6 +807,10 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre 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()] + if(Runtime->CurrentProc) { if(Runtime->IP < Runtime->CurrentProc->Count) @@ -901,12 +819,80 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre switch(Data[Runtime->IP]) { + case S_Op_Constant: + { + Runtime->IP += 1; + S_PushStack(Runtime, S_ReadValue()); + } break; + + case S_Op_Pop: + { + Runtime->IP += 1; + S_PopStack(Runtime); + } break; + + case S_Op_Nil: + { + Runtime->IP += 1; + S_PushStack(Runtime, S_MakeNil()); + } break; + + case S_Op_True: + { + Runtime->IP += 1; + S_PushStack(Runtime, S_MakeBoolean(true)); + } break; + + case S_Op_False: + { + Runtime->IP += 1; + S_PushStack(Runtime, S_MakeBoolean(false)); + } break; + + case S_Op_Add: + { + Runtime->IP += 1; + scene_value Value1 = S_PopStack(Runtime); + scene_value Value2 = S_PopStack(Runtime); + if(Value1.Kind == S_ValueKind_Number && Value2.Kind == S_ValueKind_Number) + { + S_PushStack(Runtime, S_MakeNumber(Value1.Number + Value2.Number)); + } + else if(Value1.Kind == S_ValueKind_String && Value2.Kind == S_ValueKind_String) + { + S_RuntimeError(Runtime, StrLit("String concatination is not yet supported.")); + } + else + { + S_RuntimeError(Runtime, StrLit("This operation is not supported.")); + } + } break; + + case S_Op_Subtract: + { + Runtime->IP += 1; + scene_value Value1 = S_PopStack(Runtime); + scene_value Value2 = S_PopStack(Runtime); + if(Value1.Kind == S_ValueKind_Number && Value2.Kind == S_ValueKind_Number) + { + S_PushStack(Runtime, S_MakeNumber(Value1.Number - Value2.Number)); + } + else + { + S_RuntimeError(Runtime, StrLit("This operation is not supported.")); + } + } break; + + case S_Op_Multiply: + case S_Op_Divide: + { + S_RuntimeError(Runtime, StrLit("This operation is not supported.")); + } break; + case S_Op_Jump: { Runtime->IP += 1; - scene_variable_read VariableRead = S_ReadVariableLength(&Data[Runtime->IP]); - Runtime->IP += VariableRead.Size; - scene_value Value = Compiled->Values[VariableRead.Value]; + scene_value Value = S_ReadValue(); if(Value.Kind == S_ValueKind_SourceRef) { string JumpDest = Substring(Compiled->Source, Value.SourceRef); @@ -930,8 +916,7 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre case S_Op_JumpClose: { Runtime->IP += 1; - scene_variable_read OffsetVariableRead = S_ReadVariableLength(&Data[Runtime->IP]); - scene_value OffsetValue = Compiled->Values[OffsetVariableRead.Value]; + scene_value OffsetValue = S_ReadValue(); if(OffsetValue.Kind == S_ValueKind_Offset) { Runtime->IP += OffsetValue.Offset; @@ -945,14 +930,10 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre case S_Op_AddBranch: { Runtime->IP += 1; - scene_variable_read BranchVariableRead = S_ReadVariableLength(&Data[Runtime->IP]); - scene_value BranchName = Compiled->Values[BranchVariableRead.Value]; - Runtime->IP += BranchVariableRead.Size; + scene_value BranchName = S_ReadValue(); if(BranchName.Kind == S_ValueKind_SourceRef) { - scene_variable_read OffsetVariableRead = S_ReadVariableLength(&Data[Runtime->IP]); - scene_value Offset = Compiled->Values[OffsetVariableRead.Value]; - Runtime->IP += OffsetVariableRead.Size; + scene_value Offset = S_ReadValue(); if(Offset.Kind == S_ValueKind_Offset) { branch_case *Branch = &Runtime->Branches[Runtime->BranchCount]; @@ -997,9 +978,8 @@ static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameAre } Runtime->IP += 1; - scene_variable_read VariableRead = S_ReadVariableLength(&Data[Runtime->IP]); - Runtime->IP += VariableRead.Size; - scene_value Value = Compiled->Values[VariableRead.Value]; + + scene_value Value = S_PopStack(Runtime); if(Value.Kind == S_ValueKind_SourceRef) { Action->String = Substring(Compiled->Source, Pad(Value.SourceRef, -1)); diff --git a/code/vn_scene.h b/code/vn_scene.h index 40b7cb7..4b0048c 100644 --- a/code/vn_scene.h +++ b/code/vn_scene.h @@ -37,6 +37,7 @@ enum scene_opcode S_Op_Invalid = 0, S_Op_Constant, + S_Op_Pop, S_Op_Nil, S_Op_True, @@ -92,10 +93,12 @@ struct scene_annotated_bytecode_bucket enum scene_value_kind { + S_ValueKind_Nil = 0, S_ValueKind_Number, S_ValueKind_Boolean, S_ValueKind_Pointer, S_ValueKind_SourceRef, + S_ValueKind_String, S_ValueKind_Offset, }; @@ -119,12 +122,6 @@ struct scene_value_chunk scene_value Values[512]; }; -struct scene_variable_read -{ - u64 Value; - s64 Size; -}; - enum scene_precedence { S_Precedence_None, @@ -172,6 +169,20 @@ struct scene_branch_case scene_value *EndOffsetValue; }; +struct scene_character +{ + string Name; + scene_character *Next; + scene_character *Prev; +}; + +struct scene_character_bucket +{ + scene_character *First; + scene_character *Last; + s64 Count; +}; + struct scene_compiler { memory_arena *Arena; @@ -259,6 +270,12 @@ struct branch_case s64 Offset; }; +struct scene_runtime_stack +{ + scene_value Stack[128]; + s32 Count; +}; + struct scene_runtime { compiled_scene Compiled; @@ -266,6 +283,8 @@ struct scene_runtime // sixten: runtime state scene_proc *CurrentProc; s64 IP; + memory_arena *Arena; + scene_runtime_stack Stack; // sixten: errors memory_arena *ErrorArena; @@ -287,6 +306,13 @@ struct scene_runtime //~ sixten: Scene Compiler Functions //- sixten: value helpers +inline scene_value S_MakeNil(void) +{ + scene_value Result; + Result.Kind = S_ValueKind_Nil; + return(Result); +} + inline scene_value S_MakeNumber(r64 Value) { scene_value Result; @@ -332,10 +358,9 @@ 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 u64 S_MakeConstant(scene_compiler *Compiler, scene_value Value); -static s64 S_EmitVariableLength(scene_compiler *Compiler, u64 Value); -static scene_variable_read S_ReadVariableLength(u8 *Byte); 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); @@ -382,6 +407,7 @@ static void S_ParseStatement(scene_compiler *Compiler); static void S_ParseExpression(scene_compiler *Compiler); static void S_ParseLiteral(scene_compiler *Compiler, b32 CanAssign); static void S_ParseNumber(scene_compiler *Compiler, b32 CanAssign); +static void S_ParseString(scene_compiler *Compiler, b32 CanAssign); static void S_ParseGrouping(scene_compiler *Compiler, b32 CanAssign); static void S_ParseUnary(scene_compiler *Compiler, b32 CanAssign); static void S_ParseBinary(scene_compiler *Compiler, b32 CanAssign); diff --git a/code/vn_scene_view.cpp b/code/vn_scene_view.cpp index 7405834..197a101 100644 --- a/code/vn_scene_view.cpp +++ b/code/vn_scene_view.cpp @@ -19,6 +19,8 @@ static void SV_SetCurrentSource(compiled_scene *Compiled) ArenaClear(SceneView->SceneArena); SceneView->Runtime.Compiled = S_CopyCompiledScene(SceneView->SceneArena, Compiled); SceneView->Runtime.IP = 0; + SceneView->Runtime.Stack.Count = 0; + SceneView->Runtime.BranchCount = 0; } static void SV_Init(scene_view *SceneView, memory_arena *TextboxArena) @@ -132,7 +134,7 @@ UI_CUSTOM_DRAW_CALLBACK(BuildSceneTextboxDrawCallback) r32 CharsRevealed = Textbox->CharsRevealed; r32 GlobalScale = CalculateGlobalScaleFromRootBox(TextboxData->SceneViewBox); text_properties Properties = {}; - Properties.Font = Font_Japanese; + Properties.Font = Font_Fancy; Properties.FontSize = GlobalScale; Properties.LineHeight = GlobalScale*1.5f; r32 Padding = 1.5f*GlobalScale; @@ -287,7 +289,7 @@ static void SV_Update(memory_arena *FrameArena, vn_input *Input) } } } - r32 CharsPerSecond = 15.0f;//35.0f; + r32 CharsPerSecond = 10.0f;//35.0f; Textbox->CharsRevealed += Input->dtForFrame*CharsPerSecond; Textbox->CharsRevealed = Min(Textbox->CharsRevealed, (r32)Textbox->String.Count); diff --git a/code/vn_tokenizer.cpp b/code/vn_tokenizer.cpp index e0721b3..66d0ab0 100644 --- a/code/vn_tokenizer.cpp +++ b/code/vn_tokenizer.cpp @@ -175,6 +175,7 @@ static tokenize_result T_TokenizeFromText(memory_arena *Arena, string Text, toke else if(AreEqual(String, StrLit("true"))) { TokenKind = TokenKind_True; } else if(AreEqual(String, StrLit("var"))) { TokenKind = TokenKind_Var; } else if(AreEqual(String, StrLit("while"))) { TokenKind = TokenKind_While; } + else if(AreEqual(String, StrLit("define"))) { TokenKind = TokenKind_Define; } } //- sixten: numerics diff --git a/code/vn_tokenizer.h b/code/vn_tokenizer.h index 86f669c..245971c 100644 --- a/code/vn_tokenizer.h +++ b/code/vn_tokenizer.h @@ -55,6 +55,7 @@ enum token_kind TokenKind_True, TokenKind_Var, TokenKind_While, + TokenKind_Define, TokenKind_KeywordsEnd, // sixten: whitespace diff --git a/code/vn_ui_utils.cpp b/code/vn_ui_utils.cpp index 25615ac..e347000 100644 --- a/code/vn_ui_utils.cpp +++ b/code/vn_ui_utils.cpp @@ -202,6 +202,7 @@ static ui_signal UI_Scrollbar(axis2 Axis, string Name, r32 Size, r32 Offset) UI_Spacer(UI_Pixels(Offset, 1)); + UI_SetNextCornerRadius(4.0f); UI_SetNextAxisSize(Axis, UI_Pixels(Size, 1)); UI_SetNextAxisSize(Opposite(Axis), UI_Percent(1, 1)); @@ -224,7 +225,6 @@ static ui_signal UI_Scrollbar(axis2 Axis, string Name, r32 Size, r32 Offset) static void UI_ScrollBegin(r32 *X, r32 *Y, ui_box_flags Flags, string Name) { - b32 AllowOnX = (X != 0); b32 AllowOnY = (Y != 0); @@ -308,7 +308,7 @@ static void UI_ScrollEnd(r32 *X, r32 *Y, ui_box_flags Flags, string Name) UI_Column() { r32 TotalHeight = UI_CalculateBoxSize(ScrollableBox, Axis2_Y); - r32 ViewHeight = UI_CalculateBoxSize(ScrollableBox->Parent->Parent, Axis2_Y); + r32 ViewHeight = DimOfRange(ScrollableBox->Parent->Parent->Rect).y;//UI_CalculateBoxSize(ScrollableBox->Parent->Parent, Axis2_Y); if(ViewHeight / TotalHeight < 1) { diff --git a/code/vn_workspace.cpp b/code/vn_workspace.cpp index 44be67a..761c9a0 100644 --- a/code/vn_workspace.cpp +++ b/code/vn_workspace.cpp @@ -1,6 +1,7 @@ #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" //- sixten: State management @@ -254,6 +255,11 @@ static void W_BuildToolbar() 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; + } if(W_BuildMenuItem(FontIcon_Wrench, "Settings", "").Clicked) { W_CreateNewView(W_View_Settings, CurrentPanel); @@ -767,9 +773,15 @@ static void W_Init(workspace *Workspace) W_CreateNewView(W_View_Startup, Workspace->RootPanel); } - W_CreateNewView(W_View_TextEditor, Workspace->RootPanel); - W_SplitPanel(Workspace->RootPanel, Axis2_X); - W_CreateNewView(W_View_SceneView, Workspace->RootPanel->Last); + // sixten: build text editor / scene view layout + if(0) + { + W_CreateNewView(W_View_TextEditor, Workspace->RootPanel); + W_SplitPanel(Workspace->RootPanel, Axis2_X); + W_CreateNewView(W_View_SceneView, Workspace->RootPanel->Last); + } + + W_CreateNewView(W_View_CharacterEditor, Workspace->RootPanel); } static void W_Update(workspace *Workspace, vn_render_commands *RenderCommands, diff --git a/code/vn_workspace.h b/code/vn_workspace.h index 7f46935..0e3ab0c 100644 --- a/code/vn_workspace.h +++ b/code/vn_workspace.h @@ -100,6 +100,7 @@ struct workspace #include "vn_workspace_editor.h" #include "vn_workspace_text_editor.h" +#include "vn_workspace_character_editor.h" #include "vn_workspace_view.h" //////////////////////////////// diff --git a/code/vn_workspace_character_editor.cpp b/code/vn_workspace_character_editor.cpp new file mode 100644 index 0000000..01793fd --- /dev/null +++ b/code/vn_workspace_character_editor.cpp @@ -0,0 +1,100 @@ +//////////////////////////////// +//~ sixten: Workspace Character Editor Functions + +static character_editor_entry_data *W_AllocateCharacterEntryData(workspace_view_character_editor *Editor, memory_arena *Arena) +{ + character_editor_entry_data *Result = Editor->FreeList.First; + if(!Result) + { + Result = PushStructNoClear(Arena, character_editor_entry_data); + } + *Result = {}; + return(Result); +} + +static void W_BuildCharacterEditorView(workspace_view *View) +{ + workspace_view_character_editor *Editor = (workspace_view_character_editor *)View->Data; + + //- sixten: check that the entry list is filled out + if(DLLIsEmpty(Editor->List.First)) + { + character_list Characters = CR_GetCharacters(); + for(character_entry *Character = Characters.First; Character != 0; Character = Character->Next) + { + character_editor_entry_data *Data = W_AllocateCharacterEntryData(Editor, View->Arena); + Data->Entry = Character; + + DLLInsertLast(Editor->List.First, Editor->List.Last, Data); + } + } + + UI_WidthFill UI_HeightFill UI_Row() UI_Padding(UI_Em(5, 1)) UI_Column() + { + UI_Spacer(UI_Em(2, 1)); + + // sixten: build character lister + { + UI_SetNextWidth(UI_Percent(1, 1)); + UI_SetNextHeight(UI_Percent(1, 0)); + + UI_Scroll(0, &Editor->ScrollT) + { + UI_Height(UI_Em(2.0f, 1)) UI_CornerRadius(4.0f) + for(character_editor_entry_data *Data = Editor->List.First; Data != 0; Data = Data->Next) + { + character_entry *Entry = Data->Entry; + if(UI_ButtonF("%S", Entry->Name).Clicked) + { + Data->IsOpen = !Data->IsOpen; + } + + AC_AnimateValueDirect(Data->IsOpen, 0.3f, &Data->OpenTransition); + + if(Data->OpenTransition > 0.1f) + { + UI_SetNextHeight(UI_ChildrenSum(Data->OpenTransition, 1)); + UI_Parent(UI_MakeBox(UI_BoxFlag_DrawBorder | + UI_BoxFlag_DrawDropShadow | + UI_BoxFlag_Clip, + StrLit(""))) + { + UI_LabelF("hello"); + UI_LabelF("line"); + UI_LabelF("paint"); + UI_LabelF("color"); + UI_LabelF("design"); + UI_LabelF("address"); + UI_LabelF("brightness"); + } + } + } + } + } + + // sixten: build bottom controls + UI_Spacer(UI_Em(1.5, 1)); + UI_Height(UI_Em(2, 1)) UI_Row() + { + UI_Width(UI_TextContent(15, 1)) UI_CornerRadius(4) + { + UI_SetNextFont(Font_Icons); + ui_signal AddSignal = UI_ButtonF("%U", FontIcon_UserPlus); + if(AddSignal.Hovering) + { + UI_TooltipLabel(StrLit("Add new character"), UI_MouseP()); + } + + UI_Spacer(UI_Em(0.5, 1)); + + UI_SetNextFont(Font_Icons); + ui_signal RemoveSignal = UI_ButtonF("%U", FontIcon_UserTimes); + if(RemoveSignal.Hovering) + { + UI_TooltipLabel(StrLit("Delete selected character"), UI_MouseP()); + } + } + } + UI_Spacer(UI_Em(1.5, 1)); + } +} \ No newline at end of file diff --git a/code/vn_workspace_character_editor.h b/code/vn_workspace_character_editor.h new file mode 100644 index 0000000..14059fb --- /dev/null +++ b/code/vn_workspace_character_editor.h @@ -0,0 +1,40 @@ +/* date = August 27th 2023 3:38 pm */ + +#ifndef VN_WORKSPACE_CHARACTER_EDITOR_H +#define VN_WORKSPACE_CHARACTER_EDITOR_H + +//////////////////////////////// +//~ sixten: Workspace Character Editor Types + +struct character_editor_entry_data +{ + //- sixten: node links + character_editor_entry_data *Next; + character_editor_entry_data *Prev; + + //- sixten: contents + struct character_entry *Entry; + b32 IsOpen; + r32 OpenTransition; +}; + +struct character_editor_processed_entry_list +{ + character_editor_entry_data *First; + character_editor_entry_data *Last; +}; + +struct workspace_view_character_editor +{ + character_editor_processed_entry_list List; + character_editor_processed_entry_list FreeList; + + r32 ScrollT; +}; + +//////////////////////////////// +//~ sixten: Workspace Character Editor Functions + +static void W_BuildCharacterEditorView(workspace_view *View); + +#endif //VN_WORKSPACE_CHARACTER_EDITOR_H diff --git a/code/vn_workspace_view.cpp b/code/vn_workspace_view.cpp index f715ab1..ba3dec1 100644 --- a/code/vn_workspace_view.cpp +++ b/code/vn_workspace_view.cpp @@ -41,6 +41,13 @@ inline workspace_view *W_CreateNewView(workspace_view_type Type, workspace_panel 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; } DLLInsertLast(Parent->FirstView, Parent->LastView, View); @@ -64,6 +71,8 @@ inline void W_DestroyView(workspace_view *View) MutableStringRelease(&Editor->Text); ArenaRelease(Editor->HistoryArena); } break; + + default: break; } // sixten(NOTE): This function does not ensure that the view is not being used anywhere else. @@ -107,6 +116,8 @@ 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); @@ -458,8 +469,8 @@ static void W_BuildSettings(workspace_view *View) { UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("General"); - char *Alternatives[] = {"60 Hz", "120 Hz", "144 Hz", "Uncapped", "V-Sync"}; - s64 AlternativeMapping[] = {60, 120, 144, -1, 0}; + char *Alternatives[] = {"15 Hz", "30 Hz", "60 Hz", "120 Hz", "144 Hz", "Uncapped", "V-Sync"}; + s64 AlternativeMapping[] = {15, 30, 60, 120, 144, -1, 0}; s32 DropdownSelected; FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate); @@ -537,42 +548,55 @@ static void W_BuildView(workspace_view *View) UI_Parent(ViewBox) UI_Size(UI_Percent(1, 0), UI_Percent(1, 0)) { - if(View->Type == W_View_Startup) + switch(View->Type) { - UI_Row() UI_Padding(UI_Pixels(50, 0)) - UI_Width(UI_ChildrenSum(1, 1)) UI_Column() UI_Padding(UI_Pixels(50, 0)) + case W_View_Startup: { - UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1)) + UI_Row() UI_Padding(UI_Pixels(50, 0)) + UI_Width(UI_ChildrenSum(1, 1)) UI_Column() UI_Padding(UI_Pixels(50, 0)) { - UI_Font(Font_Bold) UI_FontSize(36) - UI_LabelF("Welcome to VN"); - UI_TextColor(Theme_BorderColor) UI_LabelF("An impractical way to make a game"); - - UI_Spacer(UI_Percent(1, 0)); - - UI_Checkbox(&DEBUG_DebugSettings->ShowWelcomeMessage, StrLit("Show this message on startup")); + UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1)) + { + UI_Font(Font_Bold) UI_FontSize(36) + UI_LabelF("Welcome to VN"); + UI_TextColor(Theme_BorderColor) UI_LabelF("An impractical way to make a game"); + + UI_Spacer(UI_Percent(1, 0)); + + UI_Checkbox(&DEBUG_DebugSettings->ShowWelcomeMessage, StrLit("Show this message on startup")); + } } - } - } - else if(View->Type == W_View_CommandPalette) - { - W_BuildViewTypeLister(View); - } - else if(View->Type == W_View_Editor) - { - Workspace_BuildEditor(View); - } - else if(View->Type == W_View_Settings) - { - W_BuildSettings(View); - } - else if(View->Type == W_View_TextEditor) - { - W_BuildTextEditor(View); - } - else if(View->Type == W_View_SceneView) - { - W_BuildSceneView(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); + } break; + + case W_View_TextEditor: + { + W_BuildTextEditor(View); + } break; + + case W_View_SceneView: + { + W_BuildSceneView(View); + } break; + + case W_View_CharacterEditor: + { + W_BuildCharacterEditorView(View); + } break; } } diff --git a/code/vn_workspace_view.h b/code/vn_workspace_view.h index e917311..8024740 100644 --- a/code/vn_workspace_view.h +++ b/code/vn_workspace_view.h @@ -26,6 +26,7 @@ enum workspace_view_type W_View_Settings, W_View_TextEditor, W_View_SceneView, + W_View_CharacterEditor, }; struct workspace_view_editor diff --git a/code/win32__main.rdbg b/code/win32__main.rdbg index 0b64cb92511e9eb696b8c2b8f51e394a38d00b9a..7f7234da6309ed259cdbda73e2947949f2714eef 100644 GIT binary patch delta 273 zcmZqT*vK)#mQi7{A*0yD4Vs{ zHW?sWX0k4$BE$iFCHdK@d6`wIMQ}5@lk@Y^GQl<~0u>8Syd}s8av#uav5AEmjG`0m z#2GUt+DfxB00G-%7G@t=ZXnAiGcQ%oC9xz?$CL}kb