Started work on the character editor.
parent
e96b3a7850
commit
41c1f17158
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
12
code/vn.cpp
12
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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -55,6 +55,7 @@ enum token_kind
|
|||
TokenKind_True,
|
||||
TokenKind_Var,
|
||||
TokenKind_While,
|
||||
TokenKind_Define,
|
||||
TokenKind_KeywordsEnd,
|
||||
|
||||
// sixten: whitespace
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
||||
////////////////////////////////
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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_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_Spacer(UI_Percent(1, 0));
|
||||
|
||||
UI_Checkbox(&DEBUG_DebugSettings->ShowWelcomeMessage, StrLit("Show this message on startup"));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ enum workspace_view_type
|
|||
W_View_Settings,
|
||||
W_View_TextEditor,
|
||||
W_View_SceneView,
|
||||
W_View_CharacterEditor,
|
||||
};
|
||||
|
||||
struct workspace_view_editor
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,11 @@
|
|||
proc main
|
||||
{
|
||||
"This is the editor";
|
||||
"You can write text in here";
|
||||
|
||||
"If you want to add a branch, you use the branch keyword";
|
||||
|
||||
|
||||
|
||||
jump main; // to not hit the "end of proc" error
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
proc main
|
||||
{
|
||||
"Hello!";
|
||||
|
||||
"This is a little text editor with syntax highlighting";
|
||||
|
||||
"Is it cool?" #noawait;
|
||||
|
||||
branch
|
||||
{
|
||||
"Yes"
|
||||
{
|
||||
"I know right?";
|
||||
}
|
||||
|
||||
"No"
|
||||
{
|
||||
"Wow, no need to be a hater dude.";
|
||||
"Seriously";
|
||||
"...";
|
||||
"Grow up";
|
||||
}
|
||||
}
|
||||
|
||||
"Oh, forgot to mention that it also supports unicode.";
|
||||
"Which makes it able to use all langages that use left to right writing.";
|
||||
"Assuming that the character system isn't too complex.";
|
||||
"Мой домашний питомец";
|
||||
"悠輝さんに渡すつもりです";
|
||||
jump main;
|
||||
}
|
Loading…
Reference in New Issue