#include "vn_platform.h" #include "vn_platform.cpp" #define STB_IMAGE_IMPLEMENTATION #include "third_party/stb_image.h" #if VN_INTERNAL struct debug_settings { b32 RenderUIDebugRects; b32 RenderFPSCounter; b32 ListHotAndActive; b32 ShowWelcomeMessage; }; global debug_settings *DEBUG_DebugSettings = 0; #endif #include "vn_tokenizer.h" #include "vn_config.h" #include "vn_font.h" #include "vn_text_op.h" #include "vn_ui.h" #include "vn_ui_utils.h" #include "vn_character.h" #include "vn_scene.h" #include "vn_scene_view.h" #include "vn_workspace.h" #include "vn_animation_curve.h" #include "vn_theme_dark.h" #include "vn_tokenizer.cpp" #include "vn_config.cpp" #include "vn_render.cpp" #include "vn_font.cpp" #include "vn_ui.cpp" #include "vn_ui_utils.cpp" #include "vn_animation_curve.cpp" #include "vn_scene.cpp" #include "vn_scene_view.cpp" #include "vn_workspace.cpp" #include "vn_character.cpp" struct vn_state { memory_arena *Arena; memory_arena *FrameArena; glyph_atlas *GlyphAtlas; config *Config; ui UI; workspace Workspace; animation_curve_state AnimationCurveState; b32 EditorMode; character_registry CharacterRegistry; render_handle BackgroundTexture; scene_view SceneView; #if VN_INTERNAL debug_settings DebugSettings; #endif }; static render_handle CreateTextureFromPath(vn_render_commands *Commands, string Path) { render_handle Result = {}; temporary_memory Scratch = GetScratch(); platform_file_handle File = Platform.OpenFile(Path, PlatformAccess_Read); if(File.IsValid) { u64 DataCount = Platform.GetFileSize(File); u8 *Data = PushArray(Scratch.Arena, u8, DataCount); Platform.ReadFile(File, Data, 0, DataCount); s32 Width, Height, BPP; u8 *TextureData = stbi_load_from_memory(Data, DataCount, &Width, &Height, &BPP, 0); render_texture_format TextureFormat = Render_TextureFormat_Invalid; switch(BPP) { InvalidDefaultCase; case 1: { TextureFormat = Render_TextureFormat_R8; } break; case 3: { TextureFormat = Render_TextureFormat_RGB8; } break; case 4: { TextureFormat = Render_TextureFormat_RGBA8; } break; } Result = Commands->AllocateTexture(V2S32(Width, Height), TextureFormat, true, TextureData); stbi_image_free(TextureData); Platform.CloseFile(File); } ReleaseScratch(Scratch); return(Result); } VN_UPDATE_AND_RENDER(VN_UpdateAndRender) { SetThreadContext(ThreadContext); Platform = Memory->PlatformAPI; vn_state *State = Memory->State; //- sixten: initialize application state if(!Memory->State) { memory_arena *Arena = ArenaAllocate(Gigabytes(1)); State = Memory->State = PushStruct(Arena, vn_state); State->Arena = Arena; State->FrameArena = ArenaAllocate(Gigabytes(1)); State->GlyphAtlas = CreateGlyphAtlas(RenderCommands); State->Config = CreateConfig(); //- sixten: load assets State->BackgroundTexture = CreateTextureFromPath(RenderCommands, StrLit("data/backgrounds/test.png")); //- sixten: setup config binds and load current config { Config_BindS32(State->Config, StrLit("Platform/RefreshRate"), &Input->RefreshRate, 60); #if VN_INTERNAL DEBUG_DebugSettings = &State->DebugSettings; Config_BindB32(State->Config, StrLit("Dev/RenderUIDebugRects"), &DEBUG_DebugSettings->RenderUIDebugRects, 0); Config_BindB32(State->Config, StrLit("Dev/RenderFPSCounter"), &DEBUG_DebugSettings->RenderFPSCounter, 0); Config_BindB32(State->Config, StrLit("Dev/ListHotAndActive"), &DEBUG_DebugSettings->ListHotAndActive, 0); Config_BindB32(State->Config, StrLit("Dev/ShowWelcomeMessage"), &DEBUG_DebugSettings->ShowWelcomeMessage, 1); #endif Config_ReadFile(State->Config, StrLit("config.vn")); } //- sixten: load startup scene scene_view *SceneView = &State->SceneView; SV_Init(SceneView, State->Arena); temporary_memory Scratch = GetScratch(); string SceneInput = Platform_ReadEntireFile(Scratch.Arena, StrLit("data/character.vns")); compiled_scene Scene = S_ScriptFromText(Scratch.Arena, SceneInput); SV_SetCurrentSource(&Scene); ReleaseScratch(Scratch); SceneView->TestHappy = CreateTextureFromPath(RenderCommands, StrLit("data/characters/test_happy.png")); SceneView->TestNormal = CreateTextureFromPath(RenderCommands, StrLit("data/characters/test_normal.png")); SceneView->BackgroundTexture = State->BackgroundTexture; CR_Init(&State->CharacterRegistry); UI_Init(&State->UI); W_Init(&State->Workspace); AC_Init(&State->AnimationCurveState); return; } #if VN_INTERNAL DEBUG_DebugSettings = &State->DebugSettings; #endif //- sixten: begin new frame ArenaClear(State->FrameArena); AC_NewFrame(&State->AnimationCurveState, Input->dtForFrame); UI_NewFrame(&State->UI, Input->EventList, Input->MouseP, State->GlyphAtlas); SV_NewFrame(&State->SceneView, Input->EventList, Input->dtForFrame); //- sixten: check for toggle between modes if(Platform_KeyPress(Input->EventList, Key_Return, PlatformModifier_Ctrl)) { State->EditorMode = !State->EditorMode; } //- sixten: build the ui UI_BeginBuild(RenderCommands->RenderDim); { if(State->EditorMode) { W_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); } else { SV_BuildSceneView(Input); } } UI_EndBuild(); //- sixten: update the scene SV_Update(State->FrameArena); //- sixten: consume all remaining evetns for(platform_event *Event = Input->EventList->First; Event != 0; Event = Event->Next) { if(Event->Type == PlatformEvent_WindowClose) { Config_WriteFile(State->Config, StrLit("config.vn")); Input->ExitRequested = true; } Platform_ConsumeEvent(Input->EventList, Event); } //- sixten: render the frame { render_group Group = BeginRenderGroup(RenderCommands); PushClear(&Group, V3(0.1, 0.1, 0.1)); UI_RenderFrame(&Group, State->GlyphAtlas); if(DEBUG_DebugSettings->ListHotAndActive) { PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 20), 15, Color_Grey, PushFormat(State->UI.FrameArena, "Hot: %S:%llu", UI_BoxStringFromKey(UI_HotKey()), UI_HotKey())); PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 40), 15, Color_Grey, PushFormat(State->UI.FrameArena, "Active: %S:%llu", UI_BoxStringFromKey(UI_ActiveKey()), UI_ActiveKey())); } } }