feat: Launcher application that loads the game and creates the window
This commit is contained in:
		
							parent
							
								
									f98d64b927
								
							
						
					
					
						commit
						f232a94f92
					
				
							
								
								
									
										14
									
								
								meson.build
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								meson.build
									
									
									
									
									
								
							@ -74,10 +74,10 @@ m_dep = compiler.find_library('m', required : false)
 | 
				
			|||||||
meshoptimizer_proj = subproject('meshoptimizer', default_options: ['warning_level=0', 'werror=false'] )
 | 
					meshoptimizer_proj = subproject('meshoptimizer', default_options: ['warning_level=0', 'werror=false'] )
 | 
				
			||||||
meshoptimizer_dep = meshoptimizer_proj.get_variable('meshoptimizer_dep')
 | 
					meshoptimizer_dep = meshoptimizer_proj.get_variable('meshoptimizer_dep')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
windowing_dep = []
 | 
					if host_machine.system() == 'linux' and get_option('use_xlib')
 | 
				
			||||||
if get_option('use_xlib')
 | 
					 | 
				
			||||||
  windowing_dep = dependency('x11', required : true)
 | 
					 | 
				
			||||||
  add_project_arguments(['-DRT_USE_XLIB'], language : ['c', 'cpp'])
 | 
					  add_project_arguments(['-DRT_USE_XLIB'], language : ['c', 'cpp'])
 | 
				
			||||||
 | 
					elif host_machine.system() == 'linux' and get_option('use_wayland')
 | 
				
			||||||
 | 
					  add_project_arguments(['-DRT_USE_WAYLAND'], language: ['c', 'cpp'])
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Copy file utility
 | 
					# Copy file utility
 | 
				
			||||||
@ -98,16 +98,16 @@ subdir('src')
 | 
				
			|||||||
engine_link_libs = []
 | 
					engine_link_libs = []
 | 
				
			||||||
if get_option('default_library') == 'static'
 | 
					if get_option('default_library') == 'static'
 | 
				
			||||||
  if get_option('static_renderer') == 'vk'
 | 
					  if get_option('static_renderer') == 'vk'
 | 
				
			||||||
    engine_link_libs = [runtime_lib, app_lib, vk_renderer_lib]
 | 
					    engine_link_libs = [runtime_lib, vk_renderer_lib]
 | 
				
			||||||
  elif get_option('static_renderer') == 'null'
 | 
					  elif get_option('static_renderer') == 'null'
 | 
				
			||||||
    engine_link_libs = [runtime_lib, app_lib, null_renderer_lib]
 | 
					    engine_link_libs = [runtime_lib, null_renderer_lib]
 | 
				
			||||||
  elif get_option('static_renderer') == 'dx11'
 | 
					  elif get_option('static_renderer') == 'dx11'
 | 
				
			||||||
    engine_link_libs = [runtime_lib, app_lib, dx11_renderer_lib]
 | 
					    engine_link_libs = [runtime_lib, dx11_renderer_lib]
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    error('Invalid static_renderer option ', get_option('static_renderer'))
 | 
					    error('Invalid static_renderer option ', get_option('static_renderer'))
 | 
				
			||||||
  endif
 | 
					  endif
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
  engine_link_libs = [runtime_lib, gfx_lib, app_lib]
 | 
					  engine_link_libs = [runtime_lib]
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Unit/Integration test driver
 | 
					# Unit/Integration test driver
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
option('static_renderer', type : 'string', value : 'dx11', description : 'Name of the renderer used for static builds')
 | 
					option('static_renderer', type : 'string', value : 'dx11', description : 'Name of the renderer used for static builds')
 | 
				
			||||||
option('use_xlib', type : 'boolean', value : false, description : 'Use Xlib for window creation under linux')
 | 
					option('use_xlib', type : 'boolean', value : true, description : 'Use Xlib for window creation under linux')
 | 
				
			||||||
 | 
					option('use_wayland', type : 'boolean', value : false, description : 'Use wayland for window creation under linux')
 | 
				
			||||||
option('error_report_debugbreak', type : 'boolean', value : true, description : 'Debugbreak in ReportError')
 | 
					option('error_report_debugbreak', type : 'boolean', value : true, description : 'Debugbreak in ReportError')
 | 
				
			||||||
option('enable_dxc_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dxc-based shader compiler.')
 | 
					option('enable_dxc_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dxc-based shader compiler.')
 | 
				
			||||||
option('enable_dx11_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dx11-bases shader compiler.')
 | 
					option('enable_dx11_shader_compiler', type : 'boolean', value : true, description : 'Enables building the dx11-bases shader compiler.')
 | 
				
			||||||
@ -7,3 +8,4 @@ option('game_as_subdir', type : 'boolean', value : false, description : 'If true
 | 
				
			|||||||
option('build_dx11', type : 'boolean', value : true, description : 'Enables/disables the build of the dx11 renderer.')
 | 
					option('build_dx11', type : 'boolean', value : true, description : 'Enables/disables the build of the dx11 renderer.')
 | 
				
			||||||
option('build_vk', type : 'boolean', value : true, description : 'Enables/disables the build of the vulkan renderer.')
 | 
					option('build_vk', type : 'boolean', value : true, description : 'Enables/disables the build of the vulkan renderer.')
 | 
				
			||||||
option('build_experiments', type : 'boolean', value : false, description : 'Enables/disables building the experiments in src/experimental.')
 | 
					option('build_experiments', type : 'boolean', value : false, description : 'Enables/disables building the experiments in src/experimental.')
 | 
				
			||||||
 | 
					option('launcher_name', type : 'string', value : 'launcher', description : 'Name of the launcher executable.', yield : true)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										25
									
								
								src/launcher/game_api.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/launcher/game_api.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					#ifndef RT_LAUNCHER_GAME_API_H
 | 
				
			||||||
 | 
					#define RT_LAUNCHER_GAME_API_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <runtime/runtime.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void rt_game_register_cvars_fn(void);
 | 
				
			||||||
 | 
					typedef rt_result rt_game_initialize_fn(void);
 | 
				
			||||||
 | 
					typedef void rt_game_shutdown(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    rt_game_register_cvars_fn *RegisterCVARs;
 | 
				
			||||||
 | 
					    rt_game_initialize_fn *Init;
 | 
				
			||||||
 | 
					    rt_game_shutdown *Shutdown;
 | 
				
			||||||
 | 
					} rt_game_api;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef rt_game_api rt_load_game_api_fn(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					#define LOAD_GAME_API_FUNC extern "C" RT_DLLEXPORT rt_game_api rtLoadGameAPI()
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define LOAD_GAME_API_FUNC RT_DLLEXPORT rt_game_api rtLoadGameAPI()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										253
									
								
								src/launcher/launcher.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								src/launcher/launcher.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,253 @@
 | 
				
			|||||||
 | 
					#include "runtime/aio.h"
 | 
				
			||||||
 | 
					#include "runtime/file_tab.h"
 | 
				
			||||||
 | 
					#include "runtime/mem_arena.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __WIN32
 | 
				
			||||||
 | 
					#define GLFW_EXPOSE_NATIVE_WIN32
 | 
				
			||||||
 | 
					#elif defined(RT_USE_XLIB)
 | 
				
			||||||
 | 
					#define GLFW_EXPOSE_NATIVE_X11
 | 
				
			||||||
 | 
					#elif defined(RT_USE_WAYLAND)
 | 
				
			||||||
 | 
					#define GLFW_EXPOSE_NATIVE_WAYLAND
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define GLFW_INCLUDE_NONE
 | 
				
			||||||
 | 
					#include <GLFW/glfw3.h>
 | 
				
			||||||
 | 
					#include <GLFW/glfw3native.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <runtime/runtime.h>
 | 
				
			||||||
 | 
					#include <runtime/config.h>
 | 
				
			||||||
 | 
					#include <runtime/dynamic_libs.h>
 | 
				
			||||||
 | 
					#include <renderer/common/renderer_api.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#include "game_api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_CVAR_S(rt_Renderer, "The used renderer. Available options: vk, dx11. (Default: vk)", "vk");
 | 
				
			||||||
 | 
					RT_CVAR_S(rt_WindowTitle, "The title used for the game window. (Default: rtengine)", "rtengine");
 | 
				
			||||||
 | 
					RT_CVAR_I(rt_WindowWidth, "The window width. (Default: 1024)", 1024);
 | 
				
			||||||
 | 
					RT_CVAR_I(rt_WindowHeight, "The window height. (Default: 768)", 768);
 | 
				
			||||||
 | 
					RT_CVAR_I(rt_WindowMode, "The window mode. Available options: 0 (=Windowed), 1 (=Borderless Fullscreen), 2 (=Exclusive Fullscreen) (Default: 0)", 0);
 | 
				
			||||||
 | 
					RT_CVAR_I(rt_FullscreenRefreshRate, "Requested refresh rate for exclusive fullscreen. Set to 0 to use the monitors current setting. (Default: 0)", 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_CVAR_S(rt_GameLib, "Path to the game library. Only usable in internal builds. (Default: "")", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
					  WINDOW_MODE_WINDOWED,
 | 
				
			||||||
 | 
					  WINDOW_MODE_BORDERLESS_FULLSCREEN,
 | 
				
			||||||
 | 
					  WINDOW_MODE_FULLSCREEN,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This is baked in during compilation to make tampering with it harder.
 | 
				
			||||||
 | 
					 * In debug (internal) builds, this can be overwritten via cvar or command line argument. */
 | 
				
			||||||
 | 
					#ifndef RT_GAME_LIB_PATH
 | 
				
			||||||
 | 
					#define RT_GAME_LIB_PATH "(null)"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static rt_dynlib *_game_lib = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					static HINSTANCE _hInstance;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void SetupConfig(void) {
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&rt_Renderer);
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&rt_WindowTitle);
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&rt_WindowWidth);
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&rt_WindowHeight);
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&rt_WindowMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&rt_GameLib);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rt_file_id config_fid = rtAddFile("cfg/launcher.cfg");
 | 
				
			||||||
 | 
					    if (rtProcessConfigFiles(1, &config_fid) != RT_SUCCESS) {
 | 
				
			||||||
 | 
					        rtLog("LAUNCHER", "Processing launcher configs failed.");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void LoadGameAndRendererConfig() {
 | 
				
			||||||
 | 
					    rt_file_id renderer_cfg_fid = rtAddFile("cfg/renderer.cfg");
 | 
				
			||||||
 | 
					    rt_file_id game_cfg_fid = rtAddFile("cfg/game.cfg");
 | 
				
			||||||
 | 
					    rt_file_id fids[2] = { renderer_cfg_fid, game_cfg_fid };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rtProcessConfigFiles(RT_ARRAY_COUNT(fids), fids);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void __NullGame_RegisterCVARs(void) {}
 | 
				
			||||||
 | 
					static rt_result __NullGame_Init(void) { return RT_SUCCESS; }
 | 
				
			||||||
 | 
					static void __NullGame_Shutdown(void) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static rt_game_api LoadGame(const char *cmdline_gamelib) {
 | 
				
			||||||
 | 
					    const char *game_lib = RT_GAME_LIB_PATH;
 | 
				
			||||||
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
 | 
					    if (strlen(rt_GameLib.s) > 0) {
 | 
				
			||||||
 | 
					        game_lib = rt_GameLib.s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (cmdline_gamelib && strlen(cmdline_gamelib) > 0) {
 | 
				
			||||||
 | 
					        game_lib = cmdline_gamelib;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (strcmp(game_lib, "(null)") != 0) {
 | 
				
			||||||
 | 
					        _game_lib = rtOpenLib(game_lib);
 | 
				
			||||||
 | 
					        if (!_game_lib) {
 | 
				
			||||||
 | 
					            rtReportError("LAUNCHER", "Failed to open game library: %s", game_lib);
 | 
				
			||||||
 | 
					            goto out;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        rt_load_game_api_fn *LoadGameAPI = rtGetSymbol(_game_lib, "rtLoadGameAPI");
 | 
				
			||||||
 | 
					        if (!LoadGameAPI) {
 | 
				
			||||||
 | 
					            rtReportError("LAUNCHER", "%s is not a valid game library (rtLoadGameAPI symbol is missing).", game_lib);
 | 
				
			||||||
 | 
					            rtCloseLib(_game_lib);
 | 
				
			||||||
 | 
					            _game_lib = NULL;
 | 
				
			||||||
 | 
					            goto out;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return LoadGameAPI();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
					    /* Fall back to null implementation. */
 | 
				
			||||||
 | 
					    return (rt_game_api){
 | 
				
			||||||
 | 
					        .RegisterCVARs = __NullGame_RegisterCVARs,
 | 
				
			||||||
 | 
					        .Init          = __NullGame_Init,
 | 
				
			||||||
 | 
					        .Shutdown      = __NullGame_Shutdown,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void GlfwErrorCB(int err, const char *desc) {
 | 
				
			||||||
 | 
					    rtReportError("GLFW", "GLFW Error %d: %s", err, desc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int Entry(int argc, char **argv) {
 | 
				
			||||||
 | 
					    if (rtInitRuntime() != RT_SUCCESS)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    SetupConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glfwSetErrorCallback(GlfwErrorCB);
 | 
				
			||||||
 | 
					    if (!glfwInit()) {
 | 
				
			||||||
 | 
					        rtShutdownRuntime();
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Load the renderer library.
 | 
				
			||||||
 | 
					     * We need it before window creation, to give it an opportunity to register its cvars */
 | 
				
			||||||
 | 
					    if (rtLoadRenderer() != RT_SUCCESS) {
 | 
				
			||||||
 | 
					        rtShutdownRuntime();
 | 
				
			||||||
 | 
					        glfwTerminate();
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    g_renderer.RegisterCVARs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Load the game */
 | 
				
			||||||
 | 
					    const char *game_lib_cmdline = NULL;
 | 
				
			||||||
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
 | 
					    for (int i = 1; i < argc - 1; ++i) {
 | 
				
			||||||
 | 
					        if (strcmp(argv[i], "--game") == 0) {
 | 
				
			||||||
 | 
					            game_lib_cmdline = argv[i + 1];
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    rt_game_api game = LoadGame(game_lib_cmdline);
 | 
				
			||||||
 | 
					    game.RegisterCVARs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LoadGameAndRendererConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Create the window */
 | 
				
			||||||
 | 
					    GLFWwindow *window = NULL;
 | 
				
			||||||
 | 
					    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
 | 
				
			||||||
 | 
					    glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
 | 
				
			||||||
 | 
					    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
 | 
				
			||||||
 | 
					    glfwWindowHint(GLFW_CENTER_CURSOR, GLFW_TRUE);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (rt_WindowMode.i == WINDOW_MODE_BORDERLESS_FULLSCREEN) {
 | 
				
			||||||
 | 
					        const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
 | 
				
			||||||
 | 
					        glfwWindowHint(GLFW_RED_BITS, mode->redBits);
 | 
				
			||||||
 | 
					        glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
 | 
				
			||||||
 | 
					        glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
 | 
				
			||||||
 | 
					        glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
 | 
				
			||||||
 | 
					        window = glfwCreateWindow(mode->width, mode->height, rt_WindowTitle.s, glfwGetPrimaryMonitor(), NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (rt_WindowMode.i == WINDOW_MODE_FULLSCREEN) {
 | 
				
			||||||
 | 
					        int refresh_rate = rt_FullscreenRefreshRate.i;
 | 
				
			||||||
 | 
					        if (refresh_rate == 0) {
 | 
				
			||||||
 | 
					            refresh_rate = glfwGetVideoMode(glfwGetPrimaryMonitor())->refreshRate;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            int count;
 | 
				
			||||||
 | 
					            glfwGetVideoModes(NULL, &count);
 | 
				
			||||||
 | 
					            rt_temp_arena temp = rtGetTemporaryArena(NULL, 0);
 | 
				
			||||||
 | 
					            GLFWvidmode *modes = RT_ARENA_PUSH_ARRAY(temp.arena, GLFWvidmode, count);
 | 
				
			||||||
 | 
					            int is_supported = 0;
 | 
				
			||||||
 | 
					            for (int i = 0; i < count; ++i) {
 | 
				
			||||||
 | 
					                if (modes[i].refreshRate == refresh_rate) {
 | 
				
			||||||
 | 
					                    is_supported = 1;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            rtReturnTemporaryArena(temp);
 | 
				
			||||||
 | 
					            if (!is_supported) {
 | 
				
			||||||
 | 
					                rtLog("LAUNCHER", "Requested refresh rate %d Hz is not supported. Using current setting instead.", refresh_rate);
 | 
				
			||||||
 | 
					                refresh_rate = glfwGetVideoMode(glfwGetPrimaryMonitor())->refreshRate;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        glfwWindowHint(GLFW_REFRESH_RATE, refresh_rate);
 | 
				
			||||||
 | 
					        window = glfwCreateWindow(rt_WindowWidth.i, rt_WindowHeight.i, rt_WindowTitle.s, glfwGetPrimaryMonitor(), NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        window = glfwCreateWindow(rt_WindowWidth.i, rt_WindowHeight.i, rt_WindowTitle.s, NULL, NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!window) {
 | 
				
			||||||
 | 
					        rtReportError("LAUNCHER", "Failed to create the game window.");
 | 
				
			||||||
 | 
					        if (_game_lib)
 | 
				
			||||||
 | 
					            rtCloseLib(_game_lib);
 | 
				
			||||||
 | 
					        glfwTerminate();
 | 
				
			||||||
 | 
					        rtShutdownRuntime();
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Initialize the renderer */
 | 
				
			||||||
 | 
					    rt_renderer_init_info renderer_init_info;
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					    renderer_init_info.hWnd = glfwGetWin32Window(window);
 | 
				
			||||||
 | 
					    renderer_init_info.hInstance = _hInstance;
 | 
				
			||||||
 | 
					#elif defined(__linux__) && defined(RT_USE_XLIB)
 | 
				
			||||||
 | 
					    renderer_init_info.display = glfwGetX11Display();
 | 
				
			||||||
 | 
					    renderer_init_info.window = glfwGetX11Window(window);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    renderer_init_info.is_fullscreen = rt_WindowMode.i != WINDOW_MODE_WINDOWED;
 | 
				
			||||||
 | 
					    glfwGetFramebufferSize(window, (int*)&renderer_init_info.width, (int*)&renderer_init_info.height);
 | 
				
			||||||
 | 
					    if (g_renderer.Init(&renderer_init_info) != RT_SUCCESS) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (game.Init() != RT_SUCCESS) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (!glfwWindowShouldClose(window)) {
 | 
				
			||||||
 | 
					        glfwPollEvents();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    game.Shutdown();
 | 
				
			||||||
 | 
					    g_renderer.Shutdown();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    glfwDestroyWindow(window);
 | 
				
			||||||
 | 
					    glfwTerminate();
 | 
				
			||||||
 | 
					    if (_game_lib)
 | 
				
			||||||
 | 
					        rtCloseLib(_game_lib);
 | 
				
			||||||
 | 
					    rtShutdownRuntime();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _WIN32
 | 
				
			||||||
 | 
					#define WIN32_LEAN_AND_MEAN
 | 
				
			||||||
 | 
					int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCVE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
 | 
				
			||||||
 | 
					    _hInstance = hInstance;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
 | 
					    return Entry(argc, argv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										28
									
								
								src/launcher/meson.build
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/launcher/meson.build
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
				
			|||||||
 | 
					launcher_deps = [thread_dep, m_dep]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					glfw_proj = subproject('glfw', default_options: ['default_library=static', 'warning_level=0', 'werror=false'])
 | 
				
			||||||
 | 
					glfw_dep = glfw_proj.get_variable('glfw_dep')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					launcher_deps += glfw_dep
 | 
				
			||||||
 | 
					launcher_link_libs = [runtime_lib]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if get_option('default_library') == 'static'
 | 
				
			||||||
 | 
					  if get_option('static_renderer') == 'vk'
 | 
				
			||||||
 | 
					    launcher_link_libs += vk_renderer_lib
 | 
				
			||||||
 | 
					  elif get_option('static_renderer') == 'dx11'
 | 
				
			||||||
 | 
					    launcher_link_libs += dx11_renderer_lib
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    error('Invalid static_renderer option ', get_option('static_renderer'))
 | 
				
			||||||
 | 
					  endif
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					launcher_name = get_option('launcher_name')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					executable(launcher_name,
 | 
				
			||||||
 | 
					  'launcher.c',
 | 
				
			||||||
 | 
					  '../renderer/common/load_stub.c',
 | 
				
			||||||
 | 
					  include_directories: engine_incdir,
 | 
				
			||||||
 | 
					  dependencies: launcher_deps,
 | 
				
			||||||
 | 
					  link_with: launcher_link_libs,
 | 
				
			||||||
 | 
					  win_subsystem: 'windows')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,11 +1,12 @@
 | 
				
			|||||||
subdir('runtime')
 | 
					subdir('runtime')
 | 
				
			||||||
subdir('asset_compiler')
 | 
					subdir('asset_compiler')
 | 
				
			||||||
subdir('app_framework')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
subdir('renderer/common')
 | 
					subdir('renderer/common')
 | 
				
			||||||
subdir('renderer/dx11')
 | 
					subdir('renderer/dx11')
 | 
				
			||||||
subdir('renderer/vk')
 | 
					subdir('renderer/vk')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					subdir('launcher')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if get_option('build_experiments')
 | 
					if get_option('build_experiments')
 | 
				
			||||||
  subdir('experimental')
 | 
					  subdir('experimental')
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,10 @@
 | 
				
			|||||||
#include "renderer_api.h"
 | 
					#include "renderer_api.h"
 | 
				
			||||||
#include "runtime/dynamic_libs.h"
 | 
					#include "runtime/dynamic_libs.h"
 | 
				
			||||||
#include "runtime/config.h"
 | 
					#include "runtime/config.h"
 | 
				
			||||||
 | 
					#include "runtime/runtime.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static RT_CVAR_S(rt_Renderer, "The used renderer. Available options: dx11.", "dx11");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
RT_DLLEXPORT rt_renderer_api g_renderer;
 | 
					RT_DLLEXPORT rt_renderer_api g_renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -16,16 +16,28 @@ extern rt_renderer_api rtLoadRendererImpl(void);
 | 
				
			|||||||
static rt_dynlib _renderer_lib;
 | 
					static rt_dynlib _renderer_lib;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFAULT_RENDERER "vk"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RT_DLLEXPORT rt_result rtLoadRenderer(void) {
 | 
					RT_DLLEXPORT rt_result rtLoadRenderer(void) {
 | 
				
			||||||
    rt_load_renderer_impl_fn *LoadRendererImpl = NULL;
 | 
					    rt_load_renderer_impl_fn *LoadRendererImpl = NULL;
 | 
				
			||||||
    if (!rtGetCVAR("rt_Renderer"))
 | 
					    rt_cvar *rt_Renderer = rtGetCVAR("rt_Renderer");
 | 
				
			||||||
        rtRegisterCVAR(&rt_Renderer);
 | 
					    const char *renderer = DEFAULT_RENDERER;
 | 
				
			||||||
 | 
					    if (!rt_Renderer) {
 | 
				
			||||||
 | 
					        rtReportError("RENDERER", "rt_Renderer CVAR is not registered. Falling back to '%s'.", DEFAULT_RENDERER);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        renderer = rt_Renderer->s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
#ifdef RT_STATIC_LIB
 | 
					#ifdef RT_STATIC_LIB
 | 
				
			||||||
 | 
					    RT_UNUSED((void*)renderer);
 | 
				
			||||||
    LoadRendererImpl = rtLoadRendererImpl;
 | 
					    LoadRendererImpl = rtLoadRendererImpl;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    const char *dllname = NULL;
 | 
					    const char *dllname = NULL;
 | 
				
			||||||
    if (strcmp(rt_Renderer.s, "dx11")==0)
 | 
					    if (strcmp(renderer, "dx11")==0)
 | 
				
			||||||
        dllname = RT_DLLNAME("rtdx11");
 | 
					        dllname = RT_DLLNAME("rtdx11");
 | 
				
			||||||
 | 
					    else if (strcmp(renderer, "vk") == 0)
 | 
				
			||||||
 | 
					        dllname = RTODLLNAME("rtvk");
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        rtReportError("RENDERER", "Invalid renderer selected: %s", rt_Renderer.s);
 | 
					        rtReportError("RENDERER", "Invalid renderer selected: %s", rt_Renderer.s);
 | 
				
			||||||
        return RT_INVALID_VALUE;
 | 
					        return RT_INVALID_VALUE;
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,7 @@ typedef struct {
 | 
				
			|||||||
    int is_fullscreen;
 | 
					    int is_fullscreen;
 | 
				
			||||||
} rt_renderer_init_info;
 | 
					} rt_renderer_init_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void rt_renderer_register_cvars_fn(void);
 | 
				
			||||||
typedef rt_result rt_renderer_init_fn(const rt_renderer_init_info *info);
 | 
					typedef rt_result rt_renderer_init_fn(const rt_renderer_init_info *info);
 | 
				
			||||||
typedef void rt_renderer_shutdown_fn(void);
 | 
					typedef void rt_renderer_shutdown_fn(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -39,6 +40,7 @@ typedef enum {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Public renderer interface */
 | 
					/* Public renderer interface */
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    rt_renderer_register_cvars_fn *RegisterCVARs;
 | 
				
			||||||
    rt_renderer_init_fn *Init;
 | 
					    rt_renderer_init_fn *Init;
 | 
				
			||||||
    rt_renderer_shutdown_fn *Shutdown;
 | 
					    rt_renderer_shutdown_fn *Shutdown;
 | 
				
			||||||
} rt_renderer_api;
 | 
					} rt_renderer_api;
 | 
				
			||||||
@ -47,6 +49,8 @@ typedef struct {
 | 
				
			|||||||
/* Global renderer object */
 | 
					/* Global renderer object */
 | 
				
			||||||
RT_DLLIMPORT extern rt_renderer_api g_renderer;
 | 
					RT_DLLIMPORT extern rt_renderer_api g_renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This function is declared here, but it's definition is not necessarily compiled,
 | 
				
			||||||
 | 
					 * where you think it is. Normally, you will not have to call this. */
 | 
				
			||||||
RT_DLLEXPORT rt_result rtLoadRenderer(void);
 | 
					RT_DLLEXPORT rt_result rtLoadRenderer(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -3,6 +3,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "device.hpp"
 | 
					#include "device.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Dx11RegisterCVARs(void) {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rt_result Dx11Init(const rt_renderer_init_info *info) {
 | 
					rt_result Dx11Init(const rt_renderer_init_info *info) {
 | 
				
			||||||
    rt_result res = rt_dx11_device::GetInstance()->Initialize(info);
 | 
					    rt_result res = rt_dx11_device::GetInstance()->Initialize(info);
 | 
				
			||||||
    if (res != RT_SUCCESS)
 | 
					    if (res != RT_SUCCESS)
 | 
				
			||||||
@ -20,8 +23,9 @@ void Dx11Shutdown(void) {
 | 
				
			|||||||
// Called by the application to retrieve the renderer api
 | 
					// Called by the application to retrieve the renderer api
 | 
				
			||||||
extern "C" RT_DLLEXPORT rt_renderer_api rtLoadRendererImpl(void) {
 | 
					extern "C" RT_DLLEXPORT rt_renderer_api rtLoadRendererImpl(void) {
 | 
				
			||||||
    rt_renderer_api api = {
 | 
					    rt_renderer_api api = {
 | 
				
			||||||
        .Init     = Dx11Init,
 | 
					        .RegisterCVARs = Dx11RegisterCVARs,
 | 
				
			||||||
        .Shutdown = Dx11Shutdown,
 | 
					        .Init          = Dx11Init,
 | 
				
			||||||
 | 
					        .Shutdown      = Dx11Shutdown,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    return api;
 | 
					    return api;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,9 @@
 | 
				
			|||||||
#include "renderer/common/renderer_api.h"
 | 
					#include "renderer/common/renderer_api.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void VkRegisterCVARs(void) {
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rt_result VkInit(const rt_renderer_init_info *info) {
 | 
					rt_result VkInit(const rt_renderer_init_info *info) {
 | 
				
			||||||
    return RT_SUCCESS;
 | 
					    return RT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -10,8 +14,9 @@ void VkShutdown(void) {
 | 
				
			|||||||
// Called by the application to retrieve the renderer api
 | 
					// Called by the application to retrieve the renderer api
 | 
				
			||||||
RT_DLLEXPORT rt_renderer_api rtLoadRendererImpl(void) {
 | 
					RT_DLLEXPORT rt_renderer_api rtLoadRendererImpl(void) {
 | 
				
			||||||
    rt_renderer_api api = {
 | 
					    rt_renderer_api api = {
 | 
				
			||||||
        .Init     = VkInit,
 | 
					        .RegisterCVARs = VkRegisterCVARs,
 | 
				
			||||||
        .Shutdown = VkShutdown,
 | 
					        .Init          = VkInit,
 | 
				
			||||||
 | 
					        .Shutdown      = VkShutdown,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    return api;
 | 
					    return api;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -251,6 +251,8 @@ RT_DLLEXPORT rt_result rtProcessConfigFiles(unsigned int count, const rt_file_id
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (unsigned int i = 0; i < count; ++i) {
 | 
					    for (unsigned int i = 0; i < count; ++i) {
 | 
				
			||||||
 | 
					        if (aios[i] == RT_AIO_INVALID_HANDLE)
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
        rt_aio_state state = rtWaitForAIOCompletion(aios[i]);
 | 
					        rt_aio_state state = rtWaitForAIOCompletion(aios[i]);
 | 
				
			||||||
        if (state == RT_AIO_STATE_FINISHED) {
 | 
					        if (state == RT_AIO_STATE_FINISHED) {
 | 
				
			||||||
            res = ProcessConfigFile(configs[i].buffer, configs[i].fsz, configs[i].path);
 | 
					            res = ProcessConfigFile(configs[i].buffer, configs[i].fsz, configs[i].path);
 | 
				
			||||||
 | 
				
			|||||||
@ -83,4 +83,4 @@ RT_DLLEXPORT void rtShutdownRuntime(void) {
 | 
				
			|||||||
    ShutdownAIO();
 | 
					    ShutdownAIO();
 | 
				
			||||||
    ShutdownFileTab();
 | 
					    ShutdownFileTab();
 | 
				
			||||||
    ShutdownBufferManager();
 | 
					    ShutdownBufferManager();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ lz4_dep = lz4_proj.get_variable('liblz4_dep')
 | 
				
			|||||||
xxhash_proj = subproject('xxhash', default_options: ['default_library=static', 'b_sanitize=none'])
 | 
					xxhash_proj = subproject('xxhash', default_options: ['default_library=static', 'b_sanitize=none'])
 | 
				
			||||||
xxhash_dep = xxhash_proj.get_variable('xxhash_dep')
 | 
					xxhash_dep = xxhash_proj.get_variable('xxhash_dep')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
runtime_deps = [thread_dep, m_dep, windowing_dep, inih_dep, lz4_dep, xxhash_dep]
 | 
					runtime_deps = [thread_dep, m_dep, inih_dep, lz4_dep, xxhash_dep]
 | 
				
			||||||
runtime_incdirs = contrib_incdir
 | 
					runtime_incdirs = contrib_incdir
 | 
				
			||||||
runtime_lib = library('rt',
 | 
					runtime_lib = library('rt',
 | 
				
			||||||
  # Project Sources
 | 
					  # Project Sources
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user