Exemple #1
0
static void cmdline_compressmode(command_t* self, void* param)
{
    struct paki_args* args = (struct paki_args*)self->data;
    if (str_isequal_nocase(self->arg, "none"))
        args->compress_mode = COMPRESS_NONE;
    else if (str_isequal_nocase(self->arg, "fast"))
        args->compress_mode = COMPRESS_FAST;
    else if (str_isequal_nocase(self->arg, "normal"))
        args->compress_mode = COMPRESS_NORMAL;
    else if (str_isequal_nocase(self->arg, "best"))
        args->compress_mode = COMPRESS_BEST;
    else
        args->compress_mode = COMPRESS_NORMAL;
}
Exemple #2
0
int parse_cmd(const char* arg)
{
    uint test_cnt = sizeof(g_tests)/sizeof(struct unit_test_desc);
    for (uint i = 0; i < test_cnt; i++)     {
        if (str_isequal_nocase(arg, g_tests[i].name))   {
            return i;
        }
    }
    return -1;
}
Exemple #3
0
result_t eng_console_showgraph(uint argc, const char** argv, void* param)
{
    if (argc != 1 && argc != 2)
        return RET_INVALIDARG;
    int show = TRUE;
    if (argc == 2)
        show = str_tobool(argv[1]);

    struct rect2di rc;

    if (str_isequal_nocase(argv[0], "ft"))	{
        if (show)   {
            hud_add_graph("graph-ft", eng_hud_drawftgraph, ui_create_graphline("ft", 0, 16.0f, 60,
                *rect2di_seti(&rc, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), FALSE), NULL);
        }   else    {
            hud_remove_graph("graph-ft");
        }
    }
    else if (str_isequal_nocase(argv[0], "fps"))	{
        if (show)   {
            hud_add_graph("graph-fps", eng_hud_drawfpsgraph,
                ui_create_graphline("fps", 0, 60.0f, 60,
                *rect2di_seti(&rc, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), TRUE),NULL);
        }   else    {
            hud_remove_graph("graph-fps");
        }
    }
    else if (str_isequal_nocase(argv[0], "drawcalls"))	{
        if (show)   {
            hud_add_graph("graph-drawcall", eng_hud_drawcallgraph,
                ui_create_graphline("drawcalls", 0, 100.0f, 60,
                *rect2di_seti(&rc, 0, 0, GRAPH_WIDTH, GRAPH_HEIGHT), TRUE), NULL);
        }   else    {
            hud_remove_graph("graph-drawcall");
        }
    }
    else    {
        return RET_INVALIDARG;
    }

    return RET_OK;
}
Exemple #4
0
void cmd_gettest(command_t* cmd, void* param)
{
    if (str_isequal_nocase(cmd->arg, "heap"))   {
        g_testidx = 0;
    }   else if (str_isequal_nocase(cmd->arg, "freelist"))  {
        g_testidx = 1;
    }   else if (str_isequal_nocase(cmd->arg, "json"))  {
        g_testidx = 2;
    }   else if (str_isequal_nocase(cmd->arg, "pool"))  {
        g_testidx = 3;
    }   else if (str_isequal_nocase(cmd->arg, "thread"))  {
        g_testidx = 4;
    }   else if (str_isequal_nocase(cmd->arg, "taskmgr"))  {
        g_testidx = 5;
    }   else if (str_isequal_nocase(cmd->arg, "hashtable")) {
        g_testidx = 6;
    }
}
Exemple #5
0
void gfx_parseparams(struct gfx_params* params, json_t j)
{
    memset(params, 0x00, sizeof(struct gfx_params));

    /* graphics */
    json_t gfx = json_getitem(j, "gfx");
    if (gfx != NULL)   {
        if (json_getb_child(gfx, "fullscreen", FALSE))
            BIT_ADD(params->flags, GFX_FLAG_FULLSCREEN);

        if (json_getb_child(gfx, "vsync", FALSE))
            BIT_ADD(params->flags, GFX_FLAG_VSYNC);

        if (json_getb_child(gfx, "debug", FALSE))
            BIT_ADD(params->flags, GFX_FLAG_DEBUG);

        if (json_getb_child(gfx, "fxaa", FALSE))
            BIT_ADD(params->flags, GFX_FLAG_FXAA);

        if (json_getb_child(gfx, "rebuild-shaders", FALSE))
            BIT_ADD(params->flags, GFX_FLAG_REBUILDSHADERS);

        int msaa = json_geti_child(gfx, "msaa", 0);
        switch (msaa)   {
        case 2: params->msaa = MSAA_2X; break;
        case 4: params->msaa = MSAA_4X; break;
        case 8: params->msaa = MSAA_8X; break;
        default: params->msaa = MSAA_NONE;  break;
        }

        const char* texq = json_gets_child(gfx, "texture-quality", "highest");
        if (str_isequal_nocase(texq, "high"))
            params->tex_quality = TEXTURE_QUALITY_HIGH;
        else if(str_isequal_nocase(texq, "normal"))
            params->tex_quality = TEXTURE_QUALITY_NORMAL;
        else if(str_isequal_nocase(texq, "low"))
            params->tex_quality = TEXTURE_QUALITY_LOW;
        else
            params->tex_quality = TEXTURE_QUALITY_HIGHEST;

        const char* texf = json_gets_child(gfx, "texture-filter", "trilinear");
        if (str_isequal_nocase(texf, "trilinear"))
            params->tex_filter = TEXTURE_FILTER_TRILINEAR;
        else if(str_isequal_nocase(texf, "bilinear"))
            params->tex_filter = TEXTURE_FILTER_BILINEAR;
        else if(str_isequal_nocase(texf, "aniso2x"))
            params->tex_filter = TEXTURE_FILTER_ANISO2X;
        else if(str_isequal_nocase(texf, "aniso4x"))
            params->tex_filter = TEXTURE_FILTER_ANISO4X;
        else if(str_isequal_nocase(texf, "aniso8x"))
            params->tex_filter = TEXTURE_FILTER_ANISO8X;
        else if(str_isequal_nocase(texf, "aniso16x"))
            params->tex_filter = TEXTURE_FILTER_ANISO16X;
        else
            params->tex_filter = TEXTURE_FILTER_TRILINEAR;

        const char* shq = json_gets_child(gfx, "shading-quality", "high");
        if (str_isequal_nocase(shq, "normal"))
            params->shading_quality = SHADING_QUALITY_NORMAL;
        else if(str_isequal_nocase(shq, "low"))
            params->shading_quality = SHADING_QUALITY_LOW;
        else
            params->shading_quality = SHADING_QUALITY_HIGH;

        const char* ver = json_gets_child(gfx, "hw-version", "");
        if (str_isequal_nocase(ver, "d3d10"))
            params->hwver = GFX_HWVER_D3D10_0;
        else if (str_isequal_nocase(ver, "d3d10.1"))
            params->hwver = GFX_HWVER_D3D10_1;
        else if (str_isequal_nocase(ver, "d3d11"))
            params->hwver = GFX_HWVER_D3D11_0;
        else if (str_isequal_nocase(ver, "d3d11.1"))
            params->hwver = GFX_HWVER_D3D11_1;
        else if (str_isequal_nocase(ver, "gl3.2"))
            params->hwver = GFX_HWVER_GL3_2;
        else if (str_isequal_nocase(ver, "gl3.3"))
            params->hwver = GFX_HWVER_GL3_3;
        else if (str_isequal_nocase(ver, "gl4.0"))
            params->hwver = GFX_HWVER_GL4_0;
        else if (str_isequal_nocase(ver, "gl4.1"))
            params->hwver = GFX_HWVER_GL4_1;
        else if (str_isequal_nocase(ver, "gl4.2"))
            params->hwver = GFX_HWVER_GL4_2;
        else if (str_isequal_nocase(ver, "gl4.3"))
            params->hwver = GFX_HWVER_GL4_3;
        else if (str_isequal_nocase(ver, "gl4.4"))
            params->hwver = GFX_HWVER_GL4_4;
        else
            params->hwver = GFX_HWVER_UNKNOWN;

        params->adapter_id = json_geti_child(gfx, "adapter-id", 0);
        params->width = json_geti_child(gfx, "width", 1280);
        params->height = json_geti_child(gfx, "height", 720);
        params->refresh_rate = json_geti_child(gfx, "refresh-rate", 60);
    }   else    {
        params->width = 1280;
        params->height = 720;
    }
}
Exemple #6
0
reshandle_t rs_load_animctrl(const char* ctrl_filepath, uint flags)
{
    reshandle_t res_hdl = INVALID_HANDLE;
    reshandle_t override_hdl = res_hdl;

    if (!g_rs.init)
        return INVALID_HANDLE;

    struct hashtable_item_chained* item = hashtable_chained_find(&g_rs.dict,
        hash_str(ctrl_filepath));
    if (item != NULL)   {
        uint idx = (uint)item->value;
        struct rs_resource* res = (struct rs_resource*)g_rs.ress.buffer + idx;
        res_hdl = res->hdl;
    }

    if (res_hdl != INVALID_HANDLE && BIT_CHECK(flags, RS_LOAD_REFRESH))    {
        /* rs_resource already loaded, but refresh flag is set, so we reload it */
        if (BIT_CHECK(g_rs.flags, RS_FLAG_BGLOADING))   {
            res_hdl = rs_animctrl_queueload(ctrl_filepath, res_hdl);
        }   else    {
            override_hdl =  res_hdl;
            res_hdl = INVALID_HANDLE;
        }
    }   else if (res_hdl != INVALID_HANDLE) {
        /* add ref count */
        struct rs_resource* ress = (struct rs_resource*)g_rs.ress.buffer;
        ress[GET_INDEX(res_hdl)].ref_cnt ++;
    }

    /* rs_resource is not loaded before, so we just have to load it for the first time */
    if (res_hdl == INVALID_HANDLE)  {
        if(BIT_CHECK(g_rs.flags, RS_FLAG_BGLOADING))  {
            res_hdl = rs_animctrl_queueload(ctrl_filepath, INVALID_HANDLE);
        }   else    {
            /* determine file extension, then load the texture based on that */
            char ext[128];
            path_getfileext(ext, ctrl_filepath);
            anim_ctrl ctrl = NULL;

            /* model files should be valid extension */
            if (str_isequal_nocase(ext, "json"))
                ctrl = anim_ctrl_load((struct allocator*)g_rs.alloc, ctrl_filepath, 0);

            if (ctrl == NULL) {
                log_printf(LOG_WARNING, "res-mgr: loading rs_resource '%s' failed:"
                    " could not load anim-ctrl", ctrl_filepath);
                err_clear();
                if (override_hdl != INVALID_HANDLE)
                    rs_remove_fromdb(override_hdl);
                return INVALID_HANDLE;
            }

            res_hdl = rs_add_resource(ctrl_filepath, ctrl, override_hdl, rs_animctrl_unload);

            /* add to hot-loading files */
            if (BIT_CHECK(g_rs.flags, RS_FLAG_HOTLOADING) && !BIT_CHECK(flags, RS_LOAD_REFRESH))
                fio_mon_reg(ctrl_filepath, rs_animctrl_reload, res_hdl, 0, 0);

            log_printf(LOG_LOAD, "(anim-ctrl) \"%s\" - id: %d", ctrl_filepath, GET_ID(res_hdl));
        }
    }

    return res_hdl;
}
Exemple #7
0
reshandle_t rs_load_texture(const char* tex_filepath, uint first_mipidx,
		int srgb, uint flags)
{
    reshandle_t res_hdl = INVALID_HANDLE;
    reshandle_t override_hdl = res_hdl;

    if (!g_rs.init)
        return INVALID_HANDLE;

    struct hashtable_item_chained* item = hashtable_chained_find(&g_rs.dict,
        hash_str(tex_filepath));
    if (item != NULL)   {
        uint idx = (uint)item->value;
        struct rs_resource* res = (struct rs_resource*)g_rs.ress.buffer + idx;
        res_hdl = res->hdl;
    }

    if (res_hdl != INVALID_HANDLE && BIT_CHECK(flags, RS_LOAD_REFRESH))    {
        /* rs_resource already loaded, but refresh flag is set, so we reload it */
        if (BIT_CHECK(g_rs.flags, RS_FLAG_BGLOADING))   {
            res_hdl = rs_texture_queueload(tex_filepath, first_mipidx, srgb, res_hdl);
        }   else    {
            override_hdl =  res_hdl;
            res_hdl = INVALID_HANDLE;
        }
    }   else if (res_hdl != INVALID_HANDLE) {
        /* add ref count */
        struct rs_resource* ress = (struct rs_resource*)g_rs.ress.buffer;
        ress[GET_INDEX(res_hdl)].ref_cnt ++;
    }

    /* rs_resource is not loaded before, so we just have to load it for the first time */
    if (res_hdl == INVALID_HANDLE)  {
        if(BIT_CHECK(g_rs.flags, RS_FLAG_BGLOADING))  {
            res_hdl = rs_texture_queueload(tex_filepath, first_mipidx, srgb, INVALID_HANDLE);
        }   else    {
        	/* determine file extension, then load the texture based on that */
        	char ext[128];
        	path_getfileext(ext, tex_filepath);
        	gfx_texture tex = NULL;

        	if (str_isequal_nocase(ext, "dds"))
        		tex  = gfx_texture_loaddds(tex_filepath, first_mipidx, srgb, 0);

            if (tex == NULL) {
                log_printf(LOG_WARNING, "res-mgr: loading rs_resource '%s' failed:"
                    " could not load texture", tex_filepath);
                err_clear();
                if (override_hdl != INVALID_HANDLE)
                    rs_remove_fromdb(override_hdl);
                return INVALID_HANDLE;
            }

            res_hdl = rs_add_resource(tex_filepath, tex, override_hdl, rs_texture_unload);

            /* add to hot-loading files */
            if (BIT_CHECK(g_rs.flags, RS_FLAG_HOTLOADING) && !BIT_CHECK(flags, RS_LOAD_REFRESH))   {
                fio_mon_reg(tex_filepath, rs_texture_reload, res_hdl, (uptr_t)first_mipidx,
                    (uptr_t)srgb);
            }

            log_printf(LOG_LOAD, "(texture) \"%s\" - id: %d", tex_filepath, GET_ID(res_hdl));
        }
    }

    return res_hdl;
}
Exemple #8
0
result_t eng_init(const struct init_params* params)
{
    result_t r = RET_OK;

    ASSERT(g_eng == NULL);
    g_eng = (struct engine*)ALLOC(sizeof(struct engine), 0);
    if (g_eng == 0)
        return err_printn(__FILE__, __LINE__, RET_OUTOFMEMORY);
    memset(g_eng, 0x00, sizeof(struct engine));

    eng_zero();

    memcpy(&g_eng->params, params, sizeof(struct init_params));

    hw_getinfo(&g_eng->hwinfo, HWINFO_ALL);

    /* console (before anything else) */
    if (BIT_CHECK(params->flags, ENG_FLAG_CONSOLE))	{
		r |= con_init(params->console_lines_max);
		if (IS_FAIL(r))
			return RET_FAIL;
		log_outputfunc(TRUE, con_log, NULL);
    }

    /* show build options */
#if !defined(FULL_VERSION)
#error "must define FULL_VERSION macro"
#endif

    time_t raw_tm;
    time(&raw_tm);

    log_printf(LOG_TEXT, "init darkhammer engine v%s build[%s, %s, %s, %s], time: %s", 
        FULL_VERSION,
#if defined(_DEBUG_)
    		"debug"
#else
    		"release"
#endif
    		,
#if defined(_PROFILE_)
    		"profile"
#else
    		"no-profile"
#endif
    		,
#if defined(_X86_)
    		"x86"
#elif defined(_X64_)
    		"x64"
#endif
    		,
#if defined(_ENABLEASSERT_)
    		"assert"
#else
    		"no-assert"
#endif
            , asctime(localtime(&raw_tm)));

    /* hardware info */
    hw_printinfo(&g_eng->hwinfo, HWINFO_ALL);

    size_t tmp_sz = params->dev.buffsize_tmp;
    size_t data_sz = data_sz = params->dev.buffsize_data;
    tmp_sz = tmp_sz != 0 ? ((size_t)tmp_sz*1024) : FRAME_STACK_SIZE;
    data_sz = data_sz != 0 ? ((size_t)data_sz*1024) : DATA_SIZE;

    /* allocators */
    /* dynamic allocator for data in dev (editor) mode, stack allocator in game (normal) mode */
    if (BIT_CHECK(params->flags, ENG_FLAG_OPTIMIZEMEMORY))   {
        /* lsr (load-stay-resident) allocator for essential engine data */
        r |= mem_stack_create(mem_heap(), &g_eng->lsr_stack, LSR_SIZE, MID_DATA);
        mem_stack_bindalloc(&g_eng->lsr_stack, &g_eng->lsr_alloc);

        r |= mem_freelist_create(mem_heap(), &g_eng->data_freelist, data_sz, MID_DATA);
        mem_freelist_bindalloc(&g_eng->data_freelist, &g_eng->data_alloc);
    }   else    {
        mem_heap_bindalloc(&g_eng->data_alloc);
        mem_heap_bindalloc(&g_eng->lsr_alloc);

        g_eng->data_alloc.alloc_fn = eng_allocfn_data;
        g_eng->data_alloc.alignedalloc_fn = eng_alignedallocfn_data;
        g_eng->lsr_alloc.alloc_fn = eng_allocfn_lsr;
        g_eng->lsr_alloc.alignedalloc_fn = eng_alignedallocfn_lsr;

        r = RET_OK;
    }

    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: out of memory for allocators");
        return RET_FAIL;
    }

    /* timer manager and frame timer */
    g_eng->timer = timer_createinstance(TRUE);

    /* add engine's own data path to file-mgr */
    if (params->data_path != NULL)   {
        char data_path_ext[DH_PATH_MAX];
        path_getfileext(data_path_ext, params->data_path);
        if (str_isequal_nocase(data_path_ext, "pak"))    {
            if (IS_FAIL(pak_open(&g_eng->data_pak, mem_heap(), params->data_path, 0)))    {
                err_print(__FILE__, __LINE__, "engine init: could not open data pak");
                return RET_FAIL;
            }
        }   else   {
            if (!util_pathisdir(params->data_path)) {
                err_print(__FILE__, __LINE__, "engine init: data path is not valid");
                return RET_FAIL;
            }
            fio_addvdir(params->data_path, FALSE);
        }
        /* assume that share directory is same as data dir */
        path_getdir(g_eng->share_dir, params->data_path);
    }   else    {
        char data_path[DH_PATH_MAX];
        char share_dir[DH_PATH_MAX];
#ifndef SHARE_DIR
        char exe_dir[DH_PATH_MAX];
        path_join(share_dir, util_getexedir(exe_dir), "..", NULL);
        path_norm(share_dir, share_dir);
#else
        path_norm(share_dir, SHARE_DIR);
#endif
        path_join(data_path, share_dir, "data", NULL);
        if (!util_pathisdir(data_path)) {
            err_print(__FILE__, __LINE__, "engine init: data path is not valid");
            return RET_FAIL;
        }

        fio_addvdir(data_path, FALSE);  /* set default (config.h configured on build) data dir */
        strcpy(g_eng->share_dir, share_dir);
    }

    uint rs_flags = 0;
    /* activate hot loading in DEV mode */
    rs_flags |= BIT_CHECK(params->flags, ENG_FLAG_DEV) ? RS_FLAG_HOTLOADING : 0;
    if (!BIT_CHECK(params->flags, ENG_FLAG_DISABLEBGLOAD))  {
        rs_flags |= RS_FLAG_PREPARE_BGLOAD;
    }

    /* task manager */
    uint thread_cnt = maxui(g_eng->hwinfo.cpu_core_cnt - 1, 1);
    r = tsk_initmgr(thread_cnt, 0, tmp_sz, 0);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init task-mgr");
        return RET_FAIL;
    }
    struct allocator* tmp_alloc = tsk_get_tmpalloc(0);
    A_SAVE(tmp_alloc);

    /* resource manager (with only 1 thread for multi-thread loading) */
    r = rs_initmgr(rs_flags, 1);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init res-mgr");
        return RET_FAIL;
    }
    rs_set_dataalloc(&g_eng->lsr_alloc);

    /* graphics renderer */
    r = gfx_init(&params->gfx);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init gfx");
        return RET_FAIL;
    }

    /* debug HUD */
    r = hud_init(BIT_CHECK(params->flags, ENG_FLAG_CONSOLE));
    if (IS_FAIL(r))	{
        err_print(__FILE__, __LINE__, "engine init failed: could not init debug-hud");
        return RET_FAIL;
    }

    /* Physics */
    if (!BIT_CHECK(params->flags, ENG_FLAG_DISABLEPHX)) {
        r = phx_init(params);
        if (IS_FAIL(r)) {
            err_print(__FILE__, __LINE__, "engine init failed: could not init physics");
            return RET_FAIL;
        }
    }

    /* component manager */
    r = cmp_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init cmp-mgr");
        return RET_FAIL;
    }
    cmp_set_globalalloc(&g_eng->data_alloc, tsk_get_tmpalloc(0));

    /* world manager */
    r = wld_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init world-mgr");
        return RET_FAIL;
    }

    /* scene manager */
    r = scn_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init scene-mgr");
        return RET_FAIL;
    }

    /* init lua */
    r = sct_init(&params->sct, BIT_CHECK(params->flags, ENG_FLAG_DEV) ? TRUE : FALSE);
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init script engine");
        return RET_FAIL;
    }

    /* web-server */
#if defined(_PROFILE_)
    r = prf_initmgr();
    if (IS_FAIL(r))	{
    	log_print(LOG_WARNING, "profiler manager init failed: service will not be available");
    	prf_releasemgr();
    }
#endif

    /* lod-scheme */
    r = lod_initmgr();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: could not init lod-scheme");
        return RET_FAIL;
    }

    /* init basic resources */
    r = rs_init_resources();
    if (IS_FAIL(r)) {
        err_print(__FILE__, __LINE__, "engine init failed: coult not init res-mgr resources");
        return RET_FAIL;
    }

    /* switch back to normal data allocator */
    rs_set_dataalloc(&g_eng->data_alloc);

    /* enable background-loading if res-mgr is prepared for (see above rs_initmgr) */
    if (gfx_check_feature(GFX_FEATURE_THREADED_CREATES))
        rs_add_flags(RS_FLAG_BGLOADING);
    log_print(LOG_TEXT, "init ok: ready.");

    /* init world vars */
    eng_world_regvars();

    /* engine specific console commnads */
    con_register_cmd("showfps", eng_console_showfps, NULL, "showfps [1*/0]");
    con_register_cmd("showft", eng_console_showft, NULL, "showft [1*/0]");
    con_register_cmd("showgraph", eng_console_showgraph, NULL, "showgraph [ft][fps][drawcalls]");
    con_register_cmd("lockfps", eng_console_lockfps, NULL, "lockfps [fps]");

    /* execute console commands - should be the final stage if initialization */
    if (BIT_CHECK(params->flags, ENG_FLAG_CONSOLE))	{
		for (uint i = 0; i < params->console_cmds_cnt; i++)	{
			con_exec(params->console_cmds + i*128);
		}
    }

    A_LOAD(tmp_alloc);
    return RET_OK;
}