예제 #1
0
void save_pak(struct paki_args* args)
{
    result_t r;
    struct pak_file pak;

    path_norm(args->pakfile, args->pakfile);
    path_norm(args->path, args->path);

    r = pak_create(&pak, mem_heap(), args->pakfile, args->compress_mode, 0);
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        return;
    }


    r = compress_directory(&pak, args, "");
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        pak_close(&pak);
        return;
    }

    pak_close(&pak);

    // report
    printf(TERM_BOLDWHITE "Saved pak: '%s'\nTotal %d file(s) - %d Error(s), %d Warning(s)\n" TERM_RESET,
           args->pakfile, args->file_cnt, args->err_cnt, args->warn_cnt);
}
예제 #2
0
void load_pak(struct paki_args* args)
{
    result_t r;
    struct pak_file pak;
    char filename[DH_PATH_MAX];

    path_norm(args->pakfile, args->pakfile);
    path_tounix(args->path, args->path);

    r = pak_open(&pak, mem_heap(), args->pakfile, 0);
    if (IS_FAIL(r))     {
        err_sendtolog(FALSE);
        return;
    }

    uint file_id = pak_findfile(&pak, args->path);
    if (file_id == INVALID_INDEX)   {
        printf(TERM_BOLDRED "Extract failed: file '%s' not found in pak.\n" TERM_RESET, args->path);
        pak_close(&pak);
        return;
    }

    path_getfullfilename(filename, args->path);
    file_t f = fio_createdisk(filename);
    if (f == NULL)     {
        printf(TERM_BOLDRED "Extract failed: could not create '%s' for writing.\n" TERM_RESET,
               filename);
        pak_close(&pak);
        err_sendtolog(FALSE);
        return;
    }

    file_t src_file = pak_getfile(&pak, mem_heap(), mem_heap(), file_id, 0);
    if (src_file == NULL)   {
        pak_close(&pak);
        fio_close(f);
        err_sendtolog(FALSE);
        return;
    }

    size_t size;
    struct allocator* alloc;
    void* buffer = fio_detachmem(src_file, &size, &alloc);
    fio_write(f, buffer, size, 1);
    A_FREE(alloc, buffer);
    fio_close(f);

    pak_close(&pak);

    if (BIT_CHECK(args->usage, PAKI_USAGE_VERBOSE)) {
        printf(TERM_WHITE "%s -> %s\n" TERM_RESET, args->path, filename);
    }
    args->file_cnt ++;

    // report
    printf(TERM_BOLDWHITE "Finished: total %d file(s) - %d error(s), %d warning(s)\n" TERM_RESET,
           args->file_cnt, args->err_cnt, args->warn_cnt);
}
예제 #3
0
result_t compress_directory(struct pak_file* pak, struct paki_args* args, const char* subdir)
{
    result_t r;
    char directory[DH_PATH_MAX];
    char filepath[DH_PATH_MAX];
    char fullfilepath[DH_PATH_MAX];

    strcpy(directory, args->path);
    if (subdir[0] != 0)     {
        path_join(directory, path_norm(directory, directory), subdir, NULL);
    }

    DIR* dir = opendir(directory);
    if (dir == NULL)    {
        printf(TERM_BOLDRED "Creating pak failed: directory '%s' does not exist.\n" TERM_RESET,
               directory);
        return RET_FAIL;
    }

    /* read directory recuresively, and compress files into pak */
    struct dirent* ent = readdir(dir);
    while (ent != NULL)     {
        if (!str_isequal(ent->d_name, ".") && !str_isequal(ent->d_name, ".."))    {
            filepath[0] = 0;
            if (subdir[0] != 0)
                strcpy(filepath, subdir);

            if (ent->d_type != DT_DIR)  {
                // put the file into the archive
                path_join(filepath, filepath, ent->d_name, NULL);
                path_join(fullfilepath, directory, ent->d_name, NULL);
                r = archive_put(pak, args, fullfilepath, filepath);
                if (IS_OK(r) && BIT_CHECK(args->usage, PAKI_USAGE_VERBOSE))     {
                    puts(filepath);
                }   else if (IS_FAIL(r))  {
                    err_sendtolog(FALSE);
                    args->err_cnt ++;
                }
                args->file_cnt ++;
            }   else    {
                // it's a directory, recurse
                path_join(filepath, filepath, ent->d_name, NULL);
                compress_directory(pak, args, filepath);
            }
        }
        ent = readdir(dir);
    }

    closedir(dir);
    return RET_OK;
}
예제 #4
0
char* util_getexedir(char* outpath)
{
    GetModuleFileName(NULL, outpath, DH_PATH_MAX);
    path_getdir(outpath, outpath);
    return path_norm(outpath, outpath);
}
예제 #5
0
파일: engine.c 프로젝트: septag/darkhammer
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;
}