#module_parameters(WITH_EDITOR := true, WITH_NETWORKING := false, WITH_PHYSICS := false, action_type : Type, entity_fields: Type, scene_fields: Type); // TODO: Add a fallback, if none we're specified _Custom_Entity_Fields :: entity_fields; _Custom_Scene_Fields :: scene_fields; Action :: action_type; EDITOR :: WITH_EDITOR; DEBUG :: true; NETWORKING :: WITH_NETWORKING; PHYSICS :: WITH_PHYSICS; #if EDITOR { //#load "../editor/scene_editor.jai"; //#load "../ui/new_ui/new_ui.jai"; #load "editor/editor.jai"; } Engine_Mode :: enum { PLAYING; EDITING; } Engine_Core :: struct { mode: Engine_Mode; #if EDITOR { editor: Editor; imgui_context: *ImGui.ImGuiContext; } window: *Window; renderer: *Renderer; input : Input_State; current_scene: *Scene; automatically_load_last_opened_scene: bool = true; camera_buffer : Buffer_Handle; time_buffer : Buffer_Handle; screen_data_buffer : Buffer_Handle; directional_light_buffer : Buffer_Handle; point_light_buffer : Buffer_Handle; procs: struct { on_scene_loaded: (*Scene, Engine_Mode); on_pre_scene_loaded: (*Scene, Engine_Mode); on_pre_scene_unloaded: (*Scene); #if PHYSICS { on_trigger_enter: (*Entity, *Entity); on_trigger_exit: (*Entity, *Entity); } } paused: bool; time: float; dt: float; } engine: Engine_Core; time: float; dt: float; quit: bool; frame_index : u64 = 0; Camera_Data :: struct { projection_matrix: Matrix4; view_matrix: Matrix4; position: Vector4; } Shader_Time :: struct { time: float; padding: Vector3; } coven_init :: (window_title: string, window_width: u32, window_height: u32, fullscreen: bool) { engine.imgui_context = ImGui.CreateContext(); engine.window = create_window(window_title, window_width, window_height, fullscreen); engine.renderer = create_renderer(engine.window); engine.renderer.vsync = true; init_input(); init_audio_system(); init_console(); init_line_rendering(); #if PHYSICS { init_physx(); } #if EDITOR { init_editor(); ui_init(); } #if WITH_NETWORKING { net_init(); } find_all_mesh_entities(); run_engine_inits(); } coven_run :: (game_update_proc: (float), game_editor_update_proc: (float), game_update_post_physics_proc: (float)) { #if EDITOR { if engine.current_scene == null && engine.automatically_load_last_opened_scene { last_opened_scene := get_last_opened_scene_file(); if last_opened_scene.count > 0 { engine.current_scene = load_scene(last_opened_scene); free(last_opened_scene); } } } sdl_window := cast(*SDL_Window_Type)engine.window; ImGui_ImplSdl_Init(sdl_window.sdl_window); ImGui.StyleColorsClassic(); ImGui.GetIO(); time = xx seconds_since_init(); while !quit { reset_temporary_storage(); frame_index += 1; update_input(); // @Incomplete if key_pressed(.SHIFT) && key_down(.ESCAPE) { quit = true; } now : float = xx seconds_since_init(); dt = now - time; time = now; engine.time = time; engine.dt = min(dt, 0.4); update_fps_counter(dt); update_console(); #if EDITOR { ImGui_ImplSdl_NewFrame((cast(*SDL_Window_Type)engine.window).sdl_window); imgui_impldx11_new_frame(); ImGui.NewFrame(); //ui_begin(); } clamped_dt := min(0.4, dt); #if EDITOR { base_editor_update(); } if engine.mode == .PLAYING { game_update_proc(clamped_dt); if engine.current_scene != null && !engine.paused { update_animators(clamped_dt); #if PHYSICS { pre_physx_sync(engine.current_scene); tick_physx(*engine.current_scene.physx_scene, clamped_dt); post_physx_sync(engine.current_scene); // TODO: Move this out into engine.procs game_update_post_physics_proc(clamped_dt); } } } else { game_editor_update_proc(clamped_dt); if engine.current_scene != null { //update_trigger_mesh_colliders(engine.current_scene); } } if engine.current_scene != null { update_transforms(engine.current_scene); sync_engine_buffers(); if !engine.paused { update_particle_systems(clamped_dt); } } #if EDITOR { ImGui.Render(); } update_audio(dt); render(); } #if WITH_EDITOR { imgui_impldx11_shutdown(); ImGui.DestroyContext(engine.imgui_context); } SDL_DestroyWindow(engine.window); SDL_Quit(); } switch_engine_mode :: (to_mode: Engine_Mode) { engine.mode = to_mode; #if EDITOR { engine.editor.selected_entities.count = 0; engine.editor.transform_gizmo.selected_axis = .NONE; } if engine.current_scene != null { reload_scene(engine.current_scene); } } #if PHYSICS { #load "physics/physx.jai"; } #if NETWORKING { #load "networking/networking.jai"; } #load "input/input.jai"; #load "renderer/engine_buffers.jai"; #load "renderer/renderer.jai"; #load "windowing/window.jai"; #load "core/mesh_entity.jai"; #load "core/string_helpers.jai"; #load "core/math.jai"; #load "core/ray.jai"; #load "animation/animator.jai"; #load "core/entity.jai"; #load "core/parray.jai"; #load "core/static_array.jai"; #load "core/queue.jai"; #load "core/scene.jai"; #load "core/transform.jai"; #load "core/camera.jai"; #load "core/console.jai"; #load "audio/audio.jai"; #load "core/fps.jai"; #scope_export #import "Bucket_Array"; #import "Basic"; #import "String"; #import "System"; #import "Flat_Pool"; #import "Hash_Table"; File :: #import "File"; #import "File_Watcher"; #import "File_Utilities";