Started work on the character editor.
parent
e96b3a7850
commit
41c1f17158
|
@ -1,11 +1,11 @@
|
||||||
@echo off
|
@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"
|
if not exist "../build" mkdir "../build"
|
||||||
|
|
||||||
pushd "../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/
|
codegen ../code/
|
||||||
|
|
||||||
cl %CommonCompilerOptions% ../code/vn.cpp /LD /link /export:VN_UpdateAndRender /incremental:no
|
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));
|
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;
|
DestHalfSize = (In_Dest.zw-In_Dest.xy)/2;
|
||||||
DestCenter = (In_Dest.xy+In_Dest.zw)/2;
|
DestCenter = (In_Dest.xy+In_Dest.zw)/2;
|
||||||
|
|
||||||
v2 SourceDim = In_Source.zw-In_Source.xy;
|
SourceP = LinearBlend(In_Source.xy, In_Source.zw, Vertices[gl_VertexID]);
|
||||||
SourceP = In_Source.xy + SourceDim*Vertices[gl_VertexID];
|
|
||||||
|
|
||||||
v2 ScreenP = V2(DestP.x / Uniform_Resolution.x, DestP.y / Uniform_Resolution.y);
|
v2 ScreenP = V2(DestP.x / Uniform_Resolution.x, DestP.y / Uniform_Resolution.y);
|
||||||
ScreenP = ScreenP*2 - 1;
|
ScreenP = ScreenP*2 - 1;
|
||||||
|
@ -448,8 +447,9 @@ r32 BorderFactor = 1;
|
||||||
if(BorderThickness != 0)
|
if(BorderThickness != 0)
|
||||||
{
|
{
|
||||||
v2 InteriorHalfSize = DestHalfSize - BorderThickness;
|
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 InteriorCornerRadius = CornerRadius*InteriorRadiusReduce*InteriorRadiusReduce;
|
||||||
|
|
||||||
r32 InsideDist = RoundedRect(DestP, DestCenter, InteriorHalfSize - SoftnessPadding, InteriorCornerRadius);
|
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_workspace.h"
|
||||||
#include "vn_animation_curve.h"
|
#include "vn_animation_curve.h"
|
||||||
#include "vn_theme_dark.h"
|
#include "vn_theme_dark.h"
|
||||||
|
#include "vn_character.h"
|
||||||
|
|
||||||
#include "vn_tokenizer.cpp"
|
#include "vn_tokenizer.cpp"
|
||||||
#include "vn_config.cpp"
|
#include "vn_config.cpp"
|
||||||
|
@ -38,6 +39,7 @@ global debug_settings *DEBUG_DebugSettings = 0;
|
||||||
#include "vn_scene.cpp"
|
#include "vn_scene.cpp"
|
||||||
#include "vn_scene_view.cpp"
|
#include "vn_scene_view.cpp"
|
||||||
#include "vn_workspace.cpp"
|
#include "vn_workspace.cpp"
|
||||||
|
#include "vn_character.cpp"
|
||||||
|
|
||||||
struct vn_state
|
struct vn_state
|
||||||
{
|
{
|
||||||
|
@ -52,6 +54,7 @@ struct vn_state
|
||||||
workspace Workspace;
|
workspace Workspace;
|
||||||
animation_curve_state AnimationCurveState;
|
animation_curve_state AnimationCurveState;
|
||||||
|
|
||||||
|
character_registry CharacterRegistry;
|
||||||
render_handle BackgroundTexture;
|
render_handle BackgroundTexture;
|
||||||
|
|
||||||
scene_view SceneView;
|
scene_view SceneView;
|
||||||
|
@ -136,6 +139,15 @@ VN_UPDATE_AND_RENDER(VN_UpdateAndRender)
|
||||||
SV_Init(SceneView, State->Arena);
|
SV_Init(SceneView, State->Arena);
|
||||||
SceneView->BackgroundTexture = State->BackgroundTexture;
|
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);
|
UI_Init(&State->UI);
|
||||||
W_Init(&State->Workspace);
|
W_Init(&State->Workspace);
|
||||||
AC_Init(&State->AnimationCurveState);
|
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)
|
static void S_ParseError(scene_compiler *Compiler, char *Message, s64 TokenOffset)
|
||||||
{
|
{
|
||||||
Compiler->EncounteredError = true;
|
if(!Compiler->InPanicMode)
|
||||||
Compiler->InPanicMode = true;
|
{
|
||||||
scene_compile_error *Error = PushStruct(Compiler->Arena, scene_compile_error);
|
Compiler->EncounteredError = true;
|
||||||
Error->Message = PushFormat(Compiler->Arena, Message);
|
Compiler->InPanicMode = true;
|
||||||
Error->Token = Compiler->At[TokenOffset];
|
scene_compile_error *Error = PushStruct(Compiler->Arena, scene_compile_error);
|
||||||
QueuePush(Compiler->Errors.First, Compiler->Errors.Last, Error);
|
Error->Message = PushFormat(Compiler->Arena, Message);
|
||||||
Compiler->Errors.Count += 1;
|
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)
|
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;
|
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)
|
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)
|
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);
|
Chunk = PushStruct(Compiler->Arena, scene_value_chunk);
|
||||||
QueuePush(Compiler->FirstValueChunk, Compiler->LastValueChunk, Chunk);
|
QueuePush(Compiler->FirstValueChunk, Compiler->LastValueChunk, Chunk);
|
||||||
}
|
}
|
||||||
Chunk->Values[Chunk->Count] = Value;
|
|
||||||
u64 Result = Compiler->ValueCount;
|
u64 Result = Compiler->ValueCount;
|
||||||
Compiler->ValueCount += 1;
|
Chunk->Values[Chunk->Count] = Value;
|
||||||
Chunk->Count += 1;
|
Chunk->Count += 1;
|
||||||
return(Result);
|
Compiler->ValueCount += 1;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S_EmitConstant(scene_compiler *Compiler, scene_value Value)
|
static void S_EmitConstant(scene_compiler *Compiler, scene_value Value)
|
||||||
{
|
{
|
||||||
S_EmitByte(Compiler, S_Op_Constant);
|
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)
|
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_False: { Result = { S_ParseLiteral, 0, S_Precedence_None }; } break;
|
||||||
case TokenKind_True: { 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_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;
|
case TokenKind_Identifier: { Result = { S_ParseVariable, 0, S_Precedence_None }; } break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
@ -235,11 +220,6 @@ static void S_ParseDeclaration(scene_compiler *Compiler)
|
||||||
Compiler->At += 1;
|
Compiler->At += 1;
|
||||||
S_ParseVariableDeclaration(Compiler);
|
S_ParseVariableDeclaration(Compiler);
|
||||||
} break;
|
} break;
|
||||||
case TokenKind_StringLiteral:
|
|
||||||
{
|
|
||||||
Compiler->At += 1;
|
|
||||||
S_ParseLineEntry(Compiler);
|
|
||||||
} break;
|
|
||||||
case TokenKind_Jump:
|
case TokenKind_Jump:
|
||||||
{
|
{
|
||||||
Compiler->At += 1;
|
Compiler->At += 1;
|
||||||
|
@ -250,9 +230,46 @@ static void S_ParseDeclaration(scene_compiler *Compiler)
|
||||||
Compiler->At += 1;
|
Compiler->At += 1;
|
||||||
S_ParseBranchStatement(Compiler);
|
S_ParseBranchStatement(Compiler);
|
||||||
} break;
|
} 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:
|
default:
|
||||||
{
|
{
|
||||||
S_ParseStatement(Compiler);
|
S_ParseStatement(Compiler);
|
||||||
|
S_EmitByte(Compiler, S_Op_Pop);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,17 +277,18 @@ static void S_ParseDeclaration(scene_compiler *Compiler)
|
||||||
{
|
{
|
||||||
for(;Compiler->At < Compiler->TokensEnd;)
|
for(;Compiler->At < Compiler->TokensEnd;)
|
||||||
{
|
{
|
||||||
if(Compiler->At[0].Kind == TokenKind_Semicolon)
|
if(Compiler->At[-1].Kind == TokenKind_Semicolon)
|
||||||
{
|
{
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(Compiler->At[-1].Kind)
|
switch(Compiler->At[0].Kind)
|
||||||
{
|
{
|
||||||
case TokenKind_Var: goto End;
|
case TokenKind_Var: goto End;
|
||||||
case TokenKind_StringLiteral: goto End;
|
case TokenKind_StringLiteral: goto End;
|
||||||
case TokenKind_Jump: goto End;
|
case TokenKind_Jump: goto End;
|
||||||
case TokenKind_Branch: goto End;
|
case TokenKind_Branch: goto End;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiler->At += 1;
|
Compiler->At += 1;
|
||||||
|
@ -299,13 +317,9 @@ static void S_ParseVariableDeclaration(scene_compiler *Compiler)
|
||||||
S_ConsumeToken(Compiler, TokenKind_Semicolon, "Expected ';' after variable declaration.");
|
S_ConsumeToken(Compiler, TokenKind_Semicolon, "Expected ';' after variable declaration.");
|
||||||
|
|
||||||
S_EmitByte(Compiler, S_Op_DefineGlobal);
|
S_EmitByte(Compiler, S_Op_DefineGlobal);
|
||||||
u64 Index = NameConstant;
|
|
||||||
for(;Index > 0x7F; Index >>= 7)
|
Assert(NameConstant < U32_Max);
|
||||||
{
|
S_EmitU32(Compiler, NameConstant);
|
||||||
S_EmitByte(Compiler, Index|0x80);
|
|
||||||
InvalidCodepath;
|
|
||||||
}
|
|
||||||
S_EmitByte(Compiler, Index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S_ParseVariable(scene_compiler *Compiler, b32 CanAssign)
|
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_EmitByte(Compiler, S_Op_GetGlobal);
|
||||||
}
|
}
|
||||||
S_EmitVariableLength(Compiler, NameConstant);
|
S_EmitU32(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S_ParseJumpStatement(scene_compiler *Compiler)
|
static void S_ParseJumpStatement(scene_compiler *Compiler)
|
||||||
|
@ -372,7 +349,7 @@ static void S_ParseJumpStatement(scene_compiler *Compiler)
|
||||||
token DestToken = Compiler->At[-1];
|
token DestToken = Compiler->At[-1];
|
||||||
|
|
||||||
S_EmitByte(Compiler, S_Op_Jump);
|
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.");
|
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)
|
for(scene_branch_case *Branch = FirstBranch; Branch != 0; Branch = Branch->Next)
|
||||||
{
|
{
|
||||||
S_EmitByte(Compiler, S_Op_AddBranch);
|
S_EmitByte(Compiler, S_Op_AddBranch);
|
||||||
S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(Branch->Name)));
|
S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeSourceRef(Branch->Name)));
|
||||||
S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeOffset(0)));
|
S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeOffset(0)));
|
||||||
scene_value_chunk *Chunk = Compiler->LastValueChunk;
|
scene_value_chunk *Chunk = Compiler->LastValueChunk;
|
||||||
Branch->OffsetValue = &Chunk->Values[Chunk->Count-1];
|
Branch->OffsetValue = &Chunk->Values[Chunk->Count-1];
|
||||||
}
|
}
|
||||||
|
@ -441,8 +418,8 @@ static void S_ParseBranchStatement(scene_compiler *Compiler)
|
||||||
|
|
||||||
S_EmitByte(Compiler, S_Op_JumpClose);
|
S_EmitByte(Compiler, S_Op_JumpClose);
|
||||||
BaseOffset += 1;
|
BaseOffset += 1;
|
||||||
|
S_EmitU32(Compiler, S_MakeConstant(Compiler, S_MakeOffset(BaseOffset)));
|
||||||
BaseOffset += S_EmitVariableLength(Compiler, S_MakeConstant(Compiler, S_MakeOffset(BaseOffset)));
|
BaseOffset += 4;
|
||||||
|
|
||||||
scene_value_chunk *Chunk = Compiler->LastValueChunk;
|
scene_value_chunk *Chunk = Compiler->LastValueChunk;
|
||||||
Branch->EndOffsetValue = &Chunk->Values[Chunk->Count-1];
|
Branch->EndOffsetValue = &Chunk->Values[Chunk->Count-1];
|
||||||
|
@ -451,7 +428,8 @@ static void S_ParseBranchStatement(scene_compiler *Compiler)
|
||||||
//- sixten: patch the last jump
|
//- sixten: patch the last jump
|
||||||
for(scene_branch_case *Branch = FirstBranch; Branch != 0; Branch = Branch->Next)
|
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);
|
ReleaseScratch(Scratch);
|
||||||
|
@ -511,6 +489,11 @@ static void S_ParseNumber(scene_compiler *Compiler, b32 CanAssign)
|
||||||
S_EmitConstant(Compiler, S_MakeNumber(Value));
|
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)
|
static void S_ParseGrouping(scene_compiler *Compiler, b32 CanAssign)
|
||||||
{
|
{
|
||||||
S_ParseExpression(Compiler);
|
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
|
struct proc_from_chunks_result
|
||||||
{
|
{
|
||||||
scene_proc *Proc;
|
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 *NextChunk = 0;
|
||||||
{
|
{
|
||||||
scene_annotated_bytecode_chunk *Chunk = First;
|
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;
|
RequiredBytes += Chunk->Count;
|
||||||
}
|
}
|
||||||
NextChunk= Chunk;
|
NextChunk = Chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene_proc *Proc = PushStruct(Arena, scene_proc);
|
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
|
//- sixten: copy the source
|
||||||
Result.Source = PushString(Arena, Compiled->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);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
@ -880,6 +764,36 @@ static scene_proc *S_FindProcByName(compiled_scene *Compiled, string Name)
|
||||||
return(Result);
|
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)
|
static scene_runtime_result S_Run(scene_runtime *Runtime, memory_arena *FrameArena, b32 AdvanceOnAwait)
|
||||||
{
|
{
|
||||||
scene_runtime_result Result = {};
|
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"));
|
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->CurrentProc)
|
||||||
{
|
{
|
||||||
if(Runtime->IP < Runtime->CurrentProc->Count)
|
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])
|
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:
|
case S_Op_Jump:
|
||||||
{
|
{
|
||||||
Runtime->IP += 1;
|
Runtime->IP += 1;
|
||||||
scene_variable_read VariableRead = S_ReadVariableLength(&Data[Runtime->IP]);
|
scene_value Value = S_ReadValue();
|
||||||
Runtime->IP += VariableRead.Size;
|
|
||||||
scene_value Value = Compiled->Values[VariableRead.Value];
|
|
||||||
if(Value.Kind == S_ValueKind_SourceRef)
|
if(Value.Kind == S_ValueKind_SourceRef)
|
||||||
{
|
{
|
||||||
string JumpDest = Substring(Compiled->Source, Value.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:
|
case S_Op_JumpClose:
|
||||||
{
|
{
|
||||||
Runtime->IP += 1;
|
Runtime->IP += 1;
|
||||||
scene_variable_read OffsetVariableRead = S_ReadVariableLength(&Data[Runtime->IP]);
|
scene_value OffsetValue = S_ReadValue();
|
||||||
scene_value OffsetValue = Compiled->Values[OffsetVariableRead.Value];
|
|
||||||
if(OffsetValue.Kind == S_ValueKind_Offset)
|
if(OffsetValue.Kind == S_ValueKind_Offset)
|
||||||
{
|
{
|
||||||
Runtime->IP += OffsetValue.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:
|
case S_Op_AddBranch:
|
||||||
{
|
{
|
||||||
Runtime->IP += 1;
|
Runtime->IP += 1;
|
||||||
scene_variable_read BranchVariableRead = S_ReadVariableLength(&Data[Runtime->IP]);
|
scene_value BranchName = S_ReadValue();
|
||||||
scene_value BranchName = Compiled->Values[BranchVariableRead.Value];
|
|
||||||
Runtime->IP += BranchVariableRead.Size;
|
|
||||||
if(BranchName.Kind == S_ValueKind_SourceRef)
|
if(BranchName.Kind == S_ValueKind_SourceRef)
|
||||||
{
|
{
|
||||||
scene_variable_read OffsetVariableRead = S_ReadVariableLength(&Data[Runtime->IP]);
|
scene_value Offset = S_ReadValue();
|
||||||
scene_value Offset = Compiled->Values[OffsetVariableRead.Value];
|
|
||||||
Runtime->IP += OffsetVariableRead.Size;
|
|
||||||
if(Offset.Kind == S_ValueKind_Offset)
|
if(Offset.Kind == S_ValueKind_Offset)
|
||||||
{
|
{
|
||||||
branch_case *Branch = &Runtime->Branches[Runtime->BranchCount];
|
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;
|
Runtime->IP += 1;
|
||||||
scene_variable_read VariableRead = S_ReadVariableLength(&Data[Runtime->IP]);
|
|
||||||
Runtime->IP += VariableRead.Size;
|
scene_value Value = S_PopStack(Runtime);
|
||||||
scene_value Value = Compiled->Values[VariableRead.Value];
|
|
||||||
if(Value.Kind == S_ValueKind_SourceRef)
|
if(Value.Kind == S_ValueKind_SourceRef)
|
||||||
{
|
{
|
||||||
Action->String = Substring(Compiled->Source, Pad(Value.SourceRef, -1));
|
Action->String = Substring(Compiled->Source, Pad(Value.SourceRef, -1));
|
||||||
|
|
|
@ -37,6 +37,7 @@ enum scene_opcode
|
||||||
S_Op_Invalid = 0,
|
S_Op_Invalid = 0,
|
||||||
|
|
||||||
S_Op_Constant,
|
S_Op_Constant,
|
||||||
|
S_Op_Pop,
|
||||||
|
|
||||||
S_Op_Nil,
|
S_Op_Nil,
|
||||||
S_Op_True,
|
S_Op_True,
|
||||||
|
@ -92,10 +93,12 @@ struct scene_annotated_bytecode_bucket
|
||||||
|
|
||||||
enum scene_value_kind
|
enum scene_value_kind
|
||||||
{
|
{
|
||||||
|
S_ValueKind_Nil = 0,
|
||||||
S_ValueKind_Number,
|
S_ValueKind_Number,
|
||||||
S_ValueKind_Boolean,
|
S_ValueKind_Boolean,
|
||||||
S_ValueKind_Pointer,
|
S_ValueKind_Pointer,
|
||||||
S_ValueKind_SourceRef,
|
S_ValueKind_SourceRef,
|
||||||
|
S_ValueKind_String,
|
||||||
S_ValueKind_Offset,
|
S_ValueKind_Offset,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,12 +122,6 @@ struct scene_value_chunk
|
||||||
scene_value Values[512];
|
scene_value Values[512];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scene_variable_read
|
|
||||||
{
|
|
||||||
u64 Value;
|
|
||||||
s64 Size;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum scene_precedence
|
enum scene_precedence
|
||||||
{
|
{
|
||||||
S_Precedence_None,
|
S_Precedence_None,
|
||||||
|
@ -172,6 +169,20 @@ struct scene_branch_case
|
||||||
scene_value *EndOffsetValue;
|
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
|
struct scene_compiler
|
||||||
{
|
{
|
||||||
memory_arena *Arena;
|
memory_arena *Arena;
|
||||||
|
@ -259,6 +270,12 @@ struct branch_case
|
||||||
s64 Offset;
|
s64 Offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct scene_runtime_stack
|
||||||
|
{
|
||||||
|
scene_value Stack[128];
|
||||||
|
s32 Count;
|
||||||
|
};
|
||||||
|
|
||||||
struct scene_runtime
|
struct scene_runtime
|
||||||
{
|
{
|
||||||
compiled_scene Compiled;
|
compiled_scene Compiled;
|
||||||
|
@ -266,6 +283,8 @@ struct scene_runtime
|
||||||
// sixten: runtime state
|
// sixten: runtime state
|
||||||
scene_proc *CurrentProc;
|
scene_proc *CurrentProc;
|
||||||
s64 IP;
|
s64 IP;
|
||||||
|
memory_arena *Arena;
|
||||||
|
scene_runtime_stack Stack;
|
||||||
|
|
||||||
// sixten: errors
|
// sixten: errors
|
||||||
memory_arena *ErrorArena;
|
memory_arena *ErrorArena;
|
||||||
|
@ -287,6 +306,13 @@ struct scene_runtime
|
||||||
//~ sixten: Scene Compiler Functions
|
//~ sixten: Scene Compiler Functions
|
||||||
|
|
||||||
//- sixten: value helpers
|
//- 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)
|
inline scene_value S_MakeNumber(r64 Value)
|
||||||
{
|
{
|
||||||
scene_value Result;
|
scene_value Result;
|
||||||
|
@ -332,10 +358,9 @@ static void S_ParseError(scene_compiler *Compiler, char *Message, s64 TokenOffse
|
||||||
|
|
||||||
//- sixten: bytecode helpers
|
//- sixten: bytecode helpers
|
||||||
static void S_EmitByte(scene_compiler *Compiler, u8 Byte);
|
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_annotated_bytecode_bucket *Bucket);
|
||||||
static u64 S_MakeConstant(scene_compiler *Compiler, scene_value Value);
|
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_EmitConstant(scene_compiler *Compiler, scene_value Value);
|
||||||
static void S_SetEmissionTarget(scene_compiler *Compiler, scene_emission_target Target);
|
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_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_ParseExpression(scene_compiler *Compiler);
|
||||||
static void S_ParseLiteral(scene_compiler *Compiler, b32 CanAssign);
|
static void S_ParseLiteral(scene_compiler *Compiler, b32 CanAssign);
|
||||||
static void S_ParseNumber(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_ParseGrouping(scene_compiler *Compiler, b32 CanAssign);
|
||||||
static void S_ParseUnary(scene_compiler *Compiler, b32 CanAssign);
|
static void S_ParseUnary(scene_compiler *Compiler, b32 CanAssign);
|
||||||
static void S_ParseBinary(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);
|
ArenaClear(SceneView->SceneArena);
|
||||||
SceneView->Runtime.Compiled = S_CopyCompiledScene(SceneView->SceneArena, Compiled);
|
SceneView->Runtime.Compiled = S_CopyCompiledScene(SceneView->SceneArena, Compiled);
|
||||||
SceneView->Runtime.IP = 0;
|
SceneView->Runtime.IP = 0;
|
||||||
|
SceneView->Runtime.Stack.Count = 0;
|
||||||
|
SceneView->Runtime.BranchCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SV_Init(scene_view *SceneView, memory_arena *TextboxArena)
|
static void SV_Init(scene_view *SceneView, memory_arena *TextboxArena)
|
||||||
|
@ -132,7 +134,7 @@ UI_CUSTOM_DRAW_CALLBACK(BuildSceneTextboxDrawCallback)
|
||||||
r32 CharsRevealed = Textbox->CharsRevealed;
|
r32 CharsRevealed = Textbox->CharsRevealed;
|
||||||
r32 GlobalScale = CalculateGlobalScaleFromRootBox(TextboxData->SceneViewBox);
|
r32 GlobalScale = CalculateGlobalScaleFromRootBox(TextboxData->SceneViewBox);
|
||||||
text_properties Properties = {};
|
text_properties Properties = {};
|
||||||
Properties.Font = Font_Japanese;
|
Properties.Font = Font_Fancy;
|
||||||
Properties.FontSize = GlobalScale;
|
Properties.FontSize = GlobalScale;
|
||||||
Properties.LineHeight = GlobalScale*1.5f;
|
Properties.LineHeight = GlobalScale*1.5f;
|
||||||
r32 Padding = 1.5f*GlobalScale;
|
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 += Input->dtForFrame*CharsPerSecond;
|
||||||
Textbox->CharsRevealed = Min(Textbox->CharsRevealed, (r32)Textbox->String.Count);
|
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("true"))) { TokenKind = TokenKind_True; }
|
||||||
else if(AreEqual(String, StrLit("var"))) { TokenKind = TokenKind_Var; }
|
else if(AreEqual(String, StrLit("var"))) { TokenKind = TokenKind_Var; }
|
||||||
else if(AreEqual(String, StrLit("while"))) { TokenKind = TokenKind_While; }
|
else if(AreEqual(String, StrLit("while"))) { TokenKind = TokenKind_While; }
|
||||||
|
else if(AreEqual(String, StrLit("define"))) { TokenKind = TokenKind_Define; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//- sixten: numerics
|
//- sixten: numerics
|
||||||
|
|
|
@ -55,6 +55,7 @@ enum token_kind
|
||||||
TokenKind_True,
|
TokenKind_True,
|
||||||
TokenKind_Var,
|
TokenKind_Var,
|
||||||
TokenKind_While,
|
TokenKind_While,
|
||||||
|
TokenKind_Define,
|
||||||
TokenKind_KeywordsEnd,
|
TokenKind_KeywordsEnd,
|
||||||
|
|
||||||
// sixten: whitespace
|
// 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_Spacer(UI_Pixels(Offset, 1));
|
||||||
|
|
||||||
|
UI_SetNextCornerRadius(4.0f);
|
||||||
UI_SetNextAxisSize(Axis, UI_Pixels(Size, 1));
|
UI_SetNextAxisSize(Axis, UI_Pixels(Size, 1));
|
||||||
UI_SetNextAxisSize(Opposite(Axis), UI_Percent(1, 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)
|
static void UI_ScrollBegin(r32 *X, r32 *Y, ui_box_flags Flags, string Name)
|
||||||
{
|
{
|
||||||
|
|
||||||
b32 AllowOnX = (X != 0);
|
b32 AllowOnX = (X != 0);
|
||||||
b32 AllowOnY = (Y != 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()
|
UI_Column()
|
||||||
{
|
{
|
||||||
r32 TotalHeight = UI_CalculateBoxSize(ScrollableBox, Axis2_Y);
|
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)
|
if(ViewHeight / TotalHeight < 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "vn_workspace_view.cpp"
|
#include "vn_workspace_view.cpp"
|
||||||
#include "vn_workspace_editor.cpp"
|
#include "vn_workspace_editor.cpp"
|
||||||
#include "vn_workspace_text_editor.cpp"
|
#include "vn_workspace_text_editor.cpp"
|
||||||
|
#include "vn_workspace_character_editor.cpp"
|
||||||
#include "vn_workspace_commands.cpp"
|
#include "vn_workspace_commands.cpp"
|
||||||
|
|
||||||
//- sixten: State management
|
//- sixten: State management
|
||||||
|
@ -254,6 +255,11 @@ static void W_BuildToolbar()
|
||||||
W_CreateNewView(W_View_SceneView, CurrentPanel);
|
W_CreateNewView(W_View_SceneView, CurrentPanel);
|
||||||
Workspace->Menu = ToolbarMenu_None;
|
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)
|
if(W_BuildMenuItem(FontIcon_Wrench, "Settings", "").Clicked)
|
||||||
{
|
{
|
||||||
W_CreateNewView(W_View_Settings, CurrentPanel);
|
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_Startup, Workspace->RootPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
W_CreateNewView(W_View_TextEditor, Workspace->RootPanel);
|
// sixten: build text editor / scene view layout
|
||||||
W_SplitPanel(Workspace->RootPanel, Axis2_X);
|
if(0)
|
||||||
W_CreateNewView(W_View_SceneView, Workspace->RootPanel->Last);
|
{
|
||||||
|
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,
|
static void W_Update(workspace *Workspace, vn_render_commands *RenderCommands,
|
||||||
|
|
|
@ -100,6 +100,7 @@ struct workspace
|
||||||
|
|
||||||
#include "vn_workspace_editor.h"
|
#include "vn_workspace_editor.h"
|
||||||
#include "vn_workspace_text_editor.h"
|
#include "vn_workspace_text_editor.h"
|
||||||
|
#include "vn_workspace_character_editor.h"
|
||||||
#include "vn_workspace_view.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->Tokens = TextData.Tokens;
|
||||||
Editor->Lines = TextData.Lines;
|
Editor->Lines = TextData.Lines;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case W_View_CharacterEditor:
|
||||||
|
{
|
||||||
|
View->Data = PushStruct(View->Arena, workspace_view_character_editor);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLInsertLast(Parent->FirstView, Parent->LastView, View);
|
DLLInsertLast(Parent->FirstView, Parent->LastView, View);
|
||||||
|
@ -64,6 +71,8 @@ inline void W_DestroyView(workspace_view *View)
|
||||||
MutableStringRelease(&Editor->Text);
|
MutableStringRelease(&Editor->Text);
|
||||||
ArenaRelease(Editor->HistoryArena);
|
ArenaRelease(Editor->HistoryArena);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sixten(NOTE): This function does not ensure that the view is not being used anywhere else.
|
// 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;
|
} break;
|
||||||
case W_View_SceneView: { Result = StrLit("Scene 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);
|
return(Result);
|
||||||
|
@ -458,8 +469,8 @@ static void W_BuildSettings(workspace_view *View)
|
||||||
{
|
{
|
||||||
UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("General");
|
UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("General");
|
||||||
|
|
||||||
char *Alternatives[] = {"60 Hz", "120 Hz", "144 Hz", "Uncapped", "V-Sync"};
|
char *Alternatives[] = {"15 Hz", "30 Hz", "60 Hz", "120 Hz", "144 Hz", "Uncapped", "V-Sync"};
|
||||||
s64 AlternativeMapping[] = {60, 120, 144, -1, 0};
|
s64 AlternativeMapping[] = {15, 30, 60, 120, 144, -1, 0};
|
||||||
|
|
||||||
s32 DropdownSelected;
|
s32 DropdownSelected;
|
||||||
FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate);
|
FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate);
|
||||||
|
@ -537,42 +548,55 @@ static void W_BuildView(workspace_view *View)
|
||||||
UI_Parent(ViewBox)
|
UI_Parent(ViewBox)
|
||||||
UI_Size(UI_Percent(1, 0), UI_Percent(1, 0))
|
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))
|
case W_View_Startup:
|
||||||
UI_Width(UI_ChildrenSum(1, 1)) UI_Column() UI_Padding(UI_Pixels(50, 0))
|
|
||||||
{
|
{
|
||||||
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_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
|
||||||
UI_LabelF("Welcome to VN");
|
{
|
||||||
UI_TextColor(Theme_BorderColor) UI_LabelF("An impractical way to make a game");
|
UI_Font(Font_Bold) UI_FontSize(36)
|
||||||
|
UI_LabelF("Welcome to VN");
|
||||||
UI_Spacer(UI_Percent(1, 0));
|
UI_TextColor(Theme_BorderColor) UI_LabelF("An impractical way to make a game");
|
||||||
|
|
||||||
UI_Checkbox(&DEBUG_DebugSettings->ShowWelcomeMessage, StrLit("Show this message on startup"));
|
UI_Spacer(UI_Percent(1, 0));
|
||||||
|
|
||||||
|
UI_Checkbox(&DEBUG_DebugSettings->ShowWelcomeMessage, StrLit("Show this message on startup"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
}
|
|
||||||
else if(View->Type == W_View_CommandPalette)
|
case W_View_CommandPalette:
|
||||||
{
|
{
|
||||||
W_BuildViewTypeLister(View);
|
W_BuildViewTypeLister(View);
|
||||||
}
|
} break;
|
||||||
else if(View->Type == W_View_Editor)
|
|
||||||
{
|
case W_View_Editor:
|
||||||
Workspace_BuildEditor(View);
|
{
|
||||||
}
|
Workspace_BuildEditor(View);
|
||||||
else if(View->Type == W_View_Settings)
|
} break;
|
||||||
{
|
|
||||||
W_BuildSettings(View);
|
case W_View_Settings:
|
||||||
}
|
{
|
||||||
else if(View->Type == W_View_TextEditor)
|
W_BuildSettings(View);
|
||||||
{
|
} break;
|
||||||
W_BuildTextEditor(View);
|
|
||||||
}
|
case W_View_TextEditor:
|
||||||
else if(View->Type == W_View_SceneView)
|
{
|
||||||
{
|
W_BuildTextEditor(View);
|
||||||
W_BuildSceneView(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_Settings,
|
||||||
W_View_TextEditor,
|
W_View_TextEditor,
|
||||||
W_View_SceneView,
|
W_View_SceneView,
|
||||||
|
W_View_CharacterEditor,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct workspace_view_editor
|
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