#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_workspace.h" #include "vn_animation_curve.h" #include "vn_theme_dark.h" #include "vn_scene.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_workspace.cpp" #include "vn_scene.cpp" struct vn_state { memory_arena *Arena; glyph_atlas *GlyphAtlas; config *Config; ui UI; workspace Workspace; animation_curve_state AnimationCurveState; render_handle BackgroundTexture; memory_arena *SceneArena; compiled_scene CompiledScene; #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, 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->GlyphAtlas = CreateGlyphAtlas(RenderCommands); State->Config = CreateConfig(); //- sixten: load assets //State->BackgroundTexture = CreateTextureFromPath(RenderCommands, StrLit("data/backgrounds/Futon_Room.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 State->SceneArena = ArenaAllocate(Gigabytes(1)); State->CompiledScene = S_ScriptFromText(State->SceneArena, Platform_ReadEntireFile(State->SceneArena, StrLit("data/compiler_test.vns"))); UI_Init(&State->UI); Workspace_Init(&State->Workspace); AnimationCurve_Init(&State->AnimationCurveState); } #if VN_INTERNAL DEBUG_DebugSettings = &State->DebugSettings; #endif //- sixten: begin new frame AnimationCurve_NewFrame(&State->AnimationCurveState, Input->dtForFrame); UI_NewFrame(&State->UI, Input->EventList, Input->MouseP, State->GlyphAtlas); //- sixten: build the ui UI_BeginBuild(RenderCommands->RenderDim); { Workspace_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); } UI_EndBuild(); //- 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)); #if 0 PushTexturedQuad(&Group, Range2R32(V2R32(0, 0), RenderCommands->RenderDim), Range2R32(V2R32(0, 0), ConvertV2ToR32(DimFromTexture(State->BackgroundTexture))), Color_White, Color_White, Color_White, Color_White, 0, 0, 0, State->BackgroundTexture); #endif 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_GetBoxNameByKey(UI_GetHot()), UI_GetHot())); PushText(&Group, State->GlyphAtlas, Font_Regular, V2(5, RenderCommands->RenderDim.y - 40), 15, Color_Grey, PushFormat(State->UI.FrameArena, "Active: %S:%llu", UI_GetBoxNameByKey(UI_GetActive()), UI_GetActive())); } } }