Пример #1
0
/**
 * @brief Init menu cvar for one savegame slot given by actual index.
 * @param[in] idx the savegame slot to retrieve gamecomment for
 * @sa SAV_GameReadGameComments_f
 */
static void SAV_GameReadGameComment (const int idx)
{
	char filename[MAX_OSPATH];
	cgi->GetRelativeSavePath(filename, sizeof(filename));
	Q_strcat(filename, sizeof(filename), "slot%i.%s", idx, SAVEGAME_EXTENSION);

	ScopedFile f;
	cgi->FS_OpenFile(filename, &f, FILE_READ);
	if (!f) {
		cgi->UI_ExecuteConfunc("update_game_info %i \"\" \"\" \"\" \"\"", idx);
		return;
	}

	saveFileHeader_t header;
	if (cgi->FS_Read(&header, sizeof(header), &f) != sizeof(header))
		Com_Printf("Warning: Savefile header may be corrupted\n");

	header.compressed = LittleLong(header.compressed);
	header.version = LittleLong(header.version);
	header.xmlSize = LittleLong(header.xmlSize);
	header.subsystems = LittleLong(header.subsystems);

	const char* basename = Com_SkipPath(filename);
	if (!SAV_VerifyHeader(&header)) {
		Com_Printf("Savegame header for slot%d is corrupted!\n", idx);
		return;
	}

	cgi->UI_ExecuteConfunc("update_game_info %i \"%s\" \"%s\" \"%s\" \"%s\"", idx, header.name, header.gameDate, header.realDate, basename);
}
Пример #2
0
/**
 * @brief Generates material files in case the settings can be guessed from map file
 */
static void GenerateMaterialFile (const char* filename, int mipTexIndex, side_t* s)
{
	bool terrainByTexture = false;
	char fileBase[MAX_OSPATH], materialPath[MAX_OSPATH];

	if (!config.generateMaterialFile)
		return;

	/* we already have a material definition for this texture */
	if (textureref[mipTexIndex].materialMarked)
		return;

	assert(filename);

	Com_StripExtension(filename, fileBase, sizeof(fileBase));
	Com_sprintf(materialPath, sizeof(materialPath), "materials/%s.mat", Com_SkipPath(fileBase));

	ScopedFile f;
	FS_OpenFile(materialPath, &f, FILE_APPEND);
	if (!f) {
		Com_Printf("Could not open material file '%s' for writing\n", materialPath);
		config.generateMaterialFile = false;
		return;
	}

	if (strstr(textureref[mipTexIndex].name, "dirt")
	 || strstr(textureref[mipTexIndex].name, "rock")
	 || strstr(textureref[mipTexIndex].name, "grass")) {
		terrainByTexture = true;
	}

	if ((s->contentFlags & CONTENTS_TERRAIN) || terrainByTexture) {
		FS_Printf(&f, "{\n\tmaterial %s\n\t{\n\t\ttexture <fillme>\n\t\tterrain 0 64\n\t\tlightmap\n\t}\n}\n", textureref[mipTexIndex].name);
		textureref[mipTexIndex].materialMarked = true;
		materialsCnt++;
	}

	/* envmap for water surfaces */
	if ((s->contentFlags & CONTENTS_WATER)
	 || strstr(textureref[mipTexIndex].name, "glass")
	 || strstr(textureref[mipTexIndex].name, "window")) {
		FS_Printf(&f, "{\n\tmaterial %s\n\tspecular 2.0\n\t{\n\t\tenvmap 0\n\t}\n}\n", textureref[mipTexIndex].name);
		textureref[mipTexIndex].materialMarked = true;
		materialsCnt++;
	}

	if (strstr(textureref[mipTexIndex].name, "wood")) {
		FS_Printf(&f, "{\n\tmaterial %s\n\tspecular 0.2\n}\n", textureref[mipTexIndex].name);
		textureref[mipTexIndex].materialMarked = true;
		materialsCnt++;
	}

	if (strstr(textureref[mipTexIndex].name, "wall")) {
		FS_Printf(&f, "{\n\tmaterial %s\n\tspecular 0.6\n\tbump 2.0\n}\n", textureref[mipTexIndex].name);
		textureref[mipTexIndex].materialMarked = true;
		materialsCnt++;
	}
}
Пример #3
0
/**
 * @brief Export the day and night lightmap and direction data for the given map.
 * @note The bsp file must already be loaded.
 * @param bspFileName The path of the loaded bsp file.
 */
void ExportLightmaps (const char* bspFileName)
{
	char path[MAX_QPATH], lightmapName[MAX_QPATH];
	const char* fileName = Com_SkipPath(bspFileName);

	Com_FilePath(bspFileName, path, sizeof(path));
	Com_StripExtension(fileName, lightmapName, sizeof(lightmapName));

	/* note it */
	Com_Printf("--- ExportLightmaps ---\n");

	BuildFaceExtents();

	ExportLightmap(path, lightmapName, true);
	ExportLightmap(path, lightmapName, false);
}
Пример #4
0
/**
 * @brief The contract is that the directory name is equal to the base of the ump filename
 */
static const char* GetUMPName (const char* mapFilename)
{
	static char name[MAX_QPATH];
	const char* filename = Com_SkipPath(mapFilename);
	/* if we are in no subdir, we don't have any ump */
	if (filename == nullptr)
		return nullptr;

	const char* mapsDir = "maps/";
	const int lMaps = strlen(mapsDir);
	const int l = strlen(filename);
	const int targetLength = strlen(mapFilename) - lMaps - l;
	if (targetLength <= 0)
		return nullptr;
	Q_strncpyz(name, mapFilename + lMaps, targetLength);
	Com_Printf("...ump: '%s%s.ump'\n", mapsDir, name);
	return name;
}
Пример #5
0
/**
 * @brief Sets the music cvar to a random track
 */
static void M_RandomTrack_f (void)
{
	if (!s_env.initialized || !music.playing)
		return;

	const int musicTrackCount = FS_BuildFileList("music/*.ogg");
	if (musicTrackCount) {
		int randomID = rand() % musicTrackCount;
		Com_DPrintf(DEBUG_SOUND, "M_RandomTrack_f: random track id: %i/%i\n", randomID, musicTrackCount);

		const char* filename;
		while ((filename = FS_NextFileFromFileList("music/*.ogg")) != nullptr) {
			if (!randomID) {
				const char* musicTrack = Com_SkipPath(filename);
				Com_Printf("..playing next music track: '%s'\n", musicTrack);
				Cvar_Set("snd_music", "%s", musicTrack);
			}
			randomID--;
		}
		FS_NextFileFromFileList(nullptr);
	} else {
		Com_DPrintf(DEBUG_SOUND, "M_RandomTrack_f: No music found!\n");
	}
}
Пример #6
0
/**
 * @brief Load material definitions for each map that has one
 * @param[in] map the base name of the map to load the material for
 */
void R_LoadMaterials (const char *map)
{
	char path[MAX_QPATH];
	byte *fileBuffer;
	const char *buffer;
	bool inmaterial;
	image_t *image;
	material_t *m;
	materialStage_t *ss;

	/* clear previously loaded materials */
	R_ImageClearMaterials();

	if (map[0] == '+' || map[0] == '-')
		map++;
	else if (map[0] == '-')
		return;

	/* load the materials file for parsing */
	Com_sprintf(path, sizeof(path), "materials/%s.mat", Com_SkipPath(map));

	if (FS_LoadFile(path, &fileBuffer) < 1) {
		Com_DPrintf(DEBUG_RENDERER, "Couldn't load %s\n", path);
		return;
	} else {
		Com_Printf("load material file: '%s'\n", path);
		if (!r_materials->integer)
			Com_Printf("...ignore materials (r_materials is deactivated)\n");
	}

	buffer = (const char *)fileBuffer;

	inmaterial = false;
	image = nullptr;
	m = nullptr;

	while (true) {
		const char *c = Com_Parse(&buffer);

		if (c[0] == '\0')
			break;

		if (*c == '{' && !inmaterial) {
			inmaterial = true;
			continue;
		}

		if (Q_streq(c, "material")) {
			c = Com_Parse(&buffer);
			image = R_GetImage(va("textures/%s", c));
			if (image == nullptr)
				Com_DPrintf(DEBUG_RENDERER, "R_LoadMaterials: skip texture: %s - not used in the map\n", c);

			continue;
		}

		if (!image)
			continue;

		m = &image->material;

		if (Q_streq(c, "normalmap")){
			c = Com_Parse(&buffer);
			image->normalmap = R_FindImage(va("textures/%s", c), it_normalmap);

			if (image->normalmap == r_noTexture){
				Com_Printf("R_LoadMaterials: Failed to resolve normalmap: %s\n", c);
				image->normalmap = nullptr;
			}
		}

		if (Q_streq(c, "glowmap")){
			c = Com_Parse(&buffer);
			image->glowmap = R_FindImage(va("textures/%s", c), it_glowmap);

			if (image->glowmap == r_noTexture){
				Com_Printf("R_LoadMaterials: Failed to resolve glowmap: %s\n", c);
				image->glowmap = nullptr;
			}
		}

		if (Q_streq(c, "bump")) {
			m->bump = atof(Com_Parse(&buffer));
			if (m->bump < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid bump value for %s\n", image->name);
				m->bump = defaultMaterial.bump;
			}
		}

		if (Q_streq(c, "parallax")) {
			m->parallax = atof(Com_Parse(&buffer));
			if (m->parallax < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid parallax value for %s\n", image->name);
				m->parallax = defaultMaterial.parallax;
			}
		}

		if (Q_streq(c, "hardness")) {
			m->hardness = atof(Com_Parse(&buffer));
			if (m->hardness < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid hardness value for %s\n", image->name);
				m->hardness = defaultMaterial.hardness;
			}
		}

		if (Q_streq(c, "specular")) {
			m->specular = atof(Com_Parse(&buffer));
			if (m->specular < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid specular value for %s\n", image->name);
				m->specular = defaultMaterial.specular;
			}
		}

		if (Q_streq(c, "glowscale")) {
			m->glowscale = atof(Com_Parse(&buffer));
			if (m->glowscale < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid glowscale value for %s\n", image->name);
				m->glowscale = defaultMaterial.glowscale;
			}
		}

		if (*c == '{' && inmaterial) {
			materialStage_t* const s = Mem_PoolAllocType(materialStage_t, vid_imagePool);
			s->glowscale = defaultMaterial.glowscale;

			if (R_ParseStage(s, &buffer) == -1) {
				Mem_Free(s);
				continue;
			}

			/* load animation frame images */
			if (s->flags & STAGE_ANIM) {
				if (R_LoadAnimImages(s) == -1) {
					Mem_Free(s);
					continue;
				}
			}

			/* append the stage to the chain */
			if (!m->stages)
				m->stages = s;
			else {
				ss = m->stages;
				while (ss->next)
					ss = ss->next;
				ss->next = s;
			}

			m->flags |= s->flags;
			m->num_stages++;
			continue;
		}

		if (*c == '}' && inmaterial) {
			Com_DPrintf(DEBUG_RENDERER, "Parsed material %s with %d stages\n", image->name, m->num_stages);
			inmaterial = false;
			image = nullptr;
			/* multiply stage glowscale values by material glowscale */
			ss = m->stages;
			while (ss) {
				ss->glowscale *= m->glowscale;
				ss = ss->next;
			}
		}
	}

	FS_FreeFile(fileBuffer);

	R_CreateMaterialData();
}