Exemple #1
0
/*
 * @brief Loads in the BSP and all sub-models for collision detection. This
 * function can also be used to initialize or clean up the collision model by
 * invoking with NULL.
 */
cm_bsp_model_t *Cm_LoadBspModel(const char *name, int64_t *size) {
	void *buf;

	memset(&cm_bsp, 0, sizeof(cm_bsp));
	cm_vis = (d_bsp_vis_t *) cm_bsp.visibility;

	// clean up and return
	if (!name) {
		if (size) {
			*size = 0;
		}
		return &cm_bsp.models[0];
	}

	// load the file
	const int64_t s = Fs_Load(name, &buf);
	if (s == -1) {
		Com_Error(ERR_DROP, "Couldn't load %s\n", name);
	}

	if (size) {
		*size = s;
	}

	// byte-swap the entire header
	d_bsp_header_t header = *(d_bsp_header_t *) buf;
	for (size_t i = 0; i < sizeof(d_bsp_header_t) / sizeof(int32_t); i++) {
		((int32_t *) &header)[i] = LittleLong(((int32_t *) &header)[i]);
	}

	if (header.version != BSP_VERSION && header.version != BSP_VERSION_QUETOO) {
		Com_Error(ERR_DROP, "%s has unsupported version: %d\n", name, header.version);
	}

	g_strlcpy(cm_bsp.name, name, sizeof(cm_bsp.name));

	cm_bsp.base = (byte *) buf;

	// load into heap
	Cm_LoadEntityString(&header.lumps[BSP_LUMP_ENTITIES]);
	Cm_LoadBspPlanes(&header.lumps[BSP_LUMP_PLANES]);
	Cm_LoadBspNodes(&header.lumps[BSP_LUMP_NODES]);
	Cm_LoadBspSurfaces(&header.lumps[BSP_LUMP_TEXINFO]);
	Cm_LoadBspLeafs(&header.lumps[BSP_LUMP_LEAFS]);
	Cm_LoadBspLeafBrushes(&header.lumps[BSP_LUMP_LEAF_BRUSHES]);
	Cm_LoadBspInlineModels(&header.lumps[BSP_LUMP_MODELS]);
	Cm_LoadBspBrushes(&header.lumps[BSP_LUMP_BRUSHES]);
	Cm_LoadBspBrushSides(&header.lumps[BSP_LUMP_BRUSH_SIDES]);
	Cm_LoadBspVisibility(&header.lumps[BSP_LUMP_VISIBILITY]);
	Cm_LoadBspAreas(&header.lumps[BSP_LUMP_AREAS]);
	Cm_LoadBspAreaPortals(&header.lumps[BSP_LUMP_AREA_PORTALS]);

	Fs_Free(buf);

	Cm_SetupBspBrushes();

	Cm_InitBoxHull();

	Cm_FloodAreas();

	return &cm_bsp.models[0];
}
Exemple #2
0
/**
 * @brief Loads in the BSP and all sub-models for collision detection. This
 * function can also be used to initialize or clean up the collision model by
 * invoking with NULL.
 */
cm_bsp_model_t *Cm_LoadBspModel(const char *name, int64_t *size) {

    // don't re-load if we don't have to
    if (name && !g_strcmp0(name, cm_bsp.name)) {

        if (size) {
            *size = cm_bsp.size;
        }

        return &cm_bsp.models[0];
    }

    Cm_UnloadBspMaterials();

    Bsp_UnloadLumps(&cm_bsp.bsp, BSP_LUMPS_ALL);

    // free dynamic memory
    Mem_Free(cm_bsp.planes);
    Mem_Free(cm_bsp.nodes);
    Mem_Free(cm_bsp.texinfos);
    Mem_Free(cm_bsp.leafs);
    Mem_Free(cm_bsp.leaf_brushes);
    Mem_Free(cm_bsp.models);
    Mem_Free(cm_bsp.brushes);
    Mem_Free(cm_bsp.brush_sides);
    Mem_Free(cm_bsp.areas);
    Mem_Free(cm_bsp.portal_open);

    memset(&cm_bsp, 0, sizeof(cm_bsp));

    // clean up and return
    if (!name) {
        if (size) {
            *size = 0;
        }
        return &cm_bsp.models[0];
    }

    // load the common BSP structure and the lumps we need
    bsp_header_t *file;

    if (!Fs_Load(name, (void **) &file)) {
        Com_Error(ERROR_DROP, "Couldn't load %s\n", name);
    }

    int32_t version = Bsp_Verify(file);

    if (version != BSP_VERSION && version != BSP_VERSION_QUETOO) {
        Fs_Free(file);
        Com_Error(ERROR_DROP, "%s has unsupported version: %d\n", name, version);
    }

    if (!Bsp_LoadLumps(file, &cm_bsp.bsp, CM_BSP_LUMPS)) {
        Fs_Free(file);
        Com_Error(ERROR_DROP, "Lump error loading %s\n", name);
    }

    // in theory, by this point the BSP is valid - now we have to create the cm_
    // structures out of the raw file data
    if (size) {
        cm_bsp.size = *size = Bsp_Size(file);
    }

    g_strlcpy(cm_bsp.name, name, sizeof(cm_bsp.name));

    Fs_Free(file);

    cm_bsp.materials = Cm_LoadBspMaterials(name);

    Cm_LoadBspPlanes();
    Cm_LoadBspNodes();
    Cm_LoadBspSurfaces();
    Cm_LoadBspLeafs();
    Cm_LoadBspLeafBrushes();
    Cm_LoadBspInlineModels();
    Cm_LoadBspBrushes();
    Cm_LoadBspBrushSides();
    Cm_LoadBspVisibility();
    Cm_LoadBspAreas();
    Cm_LoadBspAreaPortals();

    Cm_SetupBspBrushes();

    Cm_InitBoxHull();

    Cm_FloodAreas();

    return &cm_bsp.models[0];
}