#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 "generated/vn_character.meta.h" #include "vn_asset.h" #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_scene.h" #include "vn_scene_view.h" #include "vn_animation_curve.h" #include "vn_theme_dark.h" #if VN_INTERNAL #include "vn_workspace.h" #endif #include "generated/vn_character.meta.c" #include "vn_asset.cpp" #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" #if VN_INTERNAL #include "vn_workspace.cpp" #endif struct vn_state { arena *Arena; arena *FrameArena; assets Assets; glyph_atlas *GlyphAtlas; config *Config; ui UI; animation_curve_state AnimationCurveState; b32 EditorMode; render_handle BackgroundTexture; scene_view SceneView; #if VN_INTERNAL workspace Workspace; 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) { arena *Arena = ArenaAlloc(Kilobytes(24), true); State = Memory->State = PushStruct(Arena, vn_state); State->Arena = Arena; State->FrameArena = ArenaAlloc(Megabytes(1), true); State->GlyphAtlas = CreateGlyphAtlas(RenderCommands); State->Config = CreateConfig(); //- sixten: load assets State->Assets.AllocateTexture = RenderCommands->AllocateTexture; LoadPermanentAssets(&State->Assets); State->BackgroundTexture = TextureFromAssetID(AssetID_DemoBackground); //- 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")); } scene_view *SceneView = &State->SceneView; SV_Init(SceneView, State->Arena); //- sixten: load startup scene temporary_memory Scratch = GetScratch(); string SceneInput = Platform_ReadEntireFile(Scratch.Arena, StrLit("data/scene.vns")); compiled_scene Scene = S_ScriptFromText(Scratch.Arena, SceneInput); SV_SetCurrentSource(&Scene); ReleaseScratch(Scratch); SceneView->TestHappy = TextureFromAssetID(AssetID_ArthurHappy); SceneView->TestNormal = TextureFromAssetID(AssetID_ArthurNormal); SceneView->MonikaLeaning = TextureFromAssetID(AssetID_MonikaLeaning); SceneView->BackgroundTexture = State->BackgroundTexture; UI_Init(&State->UI); AC_Init(&State->AnimationCurveState); #if VN_INTERNAL W_Init(&State->Workspace); #endif return; } #if VN_INTERNAL DEBUG_DebugSettings = &State->DebugSettings; #endif //- sixten: begin new frame ArenaClear(State->FrameArena); SetAssets(&State->Assets); AC_NewFrame(&State->AnimationCurveState, Input->dtForFrame); UI_NewFrame(&State->UI, Input->EventList, Input->MouseP, Input->dtForFrame, 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 VN_INTERNAL if(State->EditorMode) { W_Update(&State->Workspace, RenderCommands, Input, State->GlyphAtlas); } else { #endif SV_BuildSceneView(Input); #if VN_INTERNAL } #endif } 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 VN_INTERNAL 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())); } #endif } }