Beispiel #1
0
/**
 * @brief Save callback for savegames in xml
 * @param[out] p XML Node structure, where we write the information to
 * @sa INS_LoadXML
 * @sa SAV_GameSaveXML
 */
qboolean INS_SaveXML (xmlNode_t *p)
{
	xmlNode_t *n;
	installation_t *inst;

	n = XML_AddNode(p, SAVE_INSTALLATION_INSTALLATIONS);
	Com_RegisterConstList(saveInstallationConstants);
	INS_Foreach(inst) {
		xmlNode_t *s, *ss;

		s = XML_AddNode(n, SAVE_INSTALLATION_INSTALLATION);
		XML_AddString(s, SAVE_INSTALLATION_TEMPLATEID, inst->installationTemplate->id);
		XML_AddInt(s, SAVE_INSTALLATION_IDX, inst->idx);
		XML_AddString(s, SAVE_INSTALLATION_NAME, inst->name);
		XML_AddPos3(s, SAVE_INSTALLATION_POS, inst->pos);
		XML_AddString(s, SAVE_INSTALLATION_STATUS, Com_GetConstVariable(SAVE_INSTALLATIONSTATUS_NAMESPACE, inst->installationStatus));
		XML_AddInt(s, SAVE_INSTALLATION_DAMAGE, inst->installationDamage);
		XML_AddFloat(s, SAVE_INSTALLATION_ALIENINTEREST, inst->alienInterest);
		XML_AddInt(s, SAVE_INSTALLATION_BUILDSTART, inst->buildStart);

		ss = XML_AddNode(s, SAVE_INSTALLATION_BATTERIES);
		XML_AddIntValue(ss, SAVE_INSTALLATION_NUM, inst->numBatteries);
		B_SaveBaseSlotsXML(inst->batteries, inst->numBatteries, ss);
	}
	Com_UnregisterConstList(saveInstallationConstants);
	return qtrue;
}
/**
 * @brief Save callback for savegames in XML Format
 * @param[out] parent XML Node structure, where we write the information to
 */
bool INT_SaveXML (xmlNode_t *parent)
{
	xmlNode_t *interestsNode = XML_AddNode(parent, SAVE_INTERESTS);
	int i;

	XML_AddShortValue(interestsNode, SAVE_INTERESTS_LASTINCREASEDELAY, ccs.lastInterestIncreaseDelay);
	XML_AddShortValue(interestsNode, SAVE_INTERESTS_LASTMISSIONSPAWNEDDELAY, ccs.lastMissionSpawnedDelay);
	XML_AddShortValue(interestsNode, SAVE_INTERESTS_OVERALL, ccs.overallInterest);
	Com_RegisterConstList(saveInterestConstants);
	for (i = 0; i < INTERESTCATEGORY_MAX; i++) {
		xmlNode_t * interestNode = XML_AddNode(interestsNode, SAVE_INTERESTS_INTEREST);
		XML_AddString(interestNode, SAVE_INTERESTS_ID, Com_GetConstVariable(SAVE_INTERESTCAT_NAMESPACE, i));
		XML_AddShort(interestNode, SAVE_INTERESTS_VAL, ccs.interest[i]);
	}
	Com_UnregisterConstList(saveInterestConstants);
	return true;
}
/**
 * @brief Save callback for savegames in XML Format
 * @param[out] parent XML Node structure, where we write the information to
 */
qboolean AIRFIGHT_SaveXML (xmlNode_t *parent)
{
	int i;

	for (i = 0; i < ccs.numProjectiles; i++) {
		int j;
		aircraftProjectile_t *projectile = &ccs.projectiles[i];
		xmlNode_t *node = XML_AddNode(parent, SAVE_AIRFIGHT_PROJECTILE);

		XML_AddString(node, SAVE_AIRFIGHT_ITEMID, projectile->aircraftItem->id);
		for (j = 0; j < projectile->numProjectiles; j++)
			XML_AddPos2(node, SAVE_AIRFIGHT_POS, projectile->pos[j]);
		XML_AddPos3(node, SAVE_AIRFIGHT_IDLETARGET, projectile->idleTarget);

		XML_AddInt(node, SAVE_AIRFIGHT_TIME, projectile->time);
		XML_AddFloat(node, SAVE_AIRFIGHT_ANGLE, projectile->angle);
		XML_AddBoolValue(node, SAVE_AIRFIGHT_BULLET, projectile->bullets);
		XML_AddBoolValue(node, SAVE_AIRFIGHT_BEAM, projectile->beam);

		if (projectile->attackingAircraft) {
			xmlNode_t *attacking =  XML_AddNode(node, SAVE_AIRFIGHT_ATTACKINGAIRCRAFT);

			XML_AddBoolValue(attacking, SAVE_AIRFIGHT_ISUFO, projectile->attackingAircraft->type == AIRCRAFT_UFO);
			if (projectile->attackingAircraft->type == AIRCRAFT_UFO)
				XML_AddInt(attacking, SAVE_AIRFIGHT_AIRCRAFTIDX, UFO_GetGeoscapeIDX(projectile->attackingAircraft));
			else
				XML_AddInt(attacking, SAVE_AIRFIGHT_AIRCRAFTIDX, projectile->attackingAircraft->idx);
		}

		if (projectile->aimedAircraft) {
			xmlNode_t *aimed =  XML_AddNode(node, SAVE_AIRFIGHT_AIMEDAIRCRAFT);

			XML_AddBoolValue(aimed, SAVE_AIRFIGHT_ISUFO, projectile->aimedAircraft->type == AIRCRAFT_UFO);
			if (projectile->aimedAircraft->type == AIRCRAFT_UFO)
				XML_AddInt(aimed, SAVE_AIRFIGHT_AIRCRAFTIDX, UFO_GetGeoscapeIDX(projectile->aimedAircraft));
			else
				XML_AddInt(aimed, SAVE_AIRFIGHT_AIRCRAFTIDX, projectile->aimedAircraft->idx);
		}
	}

	return qtrue;
}
Beispiel #4
0
/**
 * @brief This is a savegame function which stores the game in xml-Format.
 * @param[in] filename The Filename to save to (without extension)
 * @param[in] comment Description of the savegame
 * @param[out] error On failure an errormessage may be set.
 */
static bool SAV_GameSave (const char *filename, const char *comment, char **error)
{
	xmlNode_t *topNode, *node;
	char savegame[MAX_OSPATH];
	int res;
	int requiredBufferLength;
	uLongf bufLen;
	saveFileHeader_t header;
	char dummy[2];
	int i;
	dateLong_t date;
	char message[30];
	char timeStampBuffer[32];

	if (!CP_IsRunning()) {
		*error = _("No campaign active.");
		Com_Printf("Error: No campaign active.\n");
		return false;
	}

	if (!B_AtLeastOneExists()) {
		*error = _("Nothing to save yet.");
		Com_Printf("Error: Nothing to save yet.\n");
		return false;
	}

	Com_MakeTimestamp(timeStampBuffer, sizeof(timeStampBuffer));
	Com_sprintf(savegame, sizeof(savegame), "save/%s.%s", filename, SAVEGAME_EXTENSION);
	topNode = mxmlNewXML("1.0");
	node = XML_AddNode(topNode, SAVE_ROOTNODE);
	/* writing  Header */
	XML_AddInt(node, SAVE_SAVEVERSION, SAVE_FILE_VERSION);
	XML_AddString(node, SAVE_COMMENT, comment);
	XML_AddString(node, SAVE_UFOVERSION, UFO_VERSION);
	XML_AddString(node, SAVE_REALDATE, timeStampBuffer);
	CP_DateConvertLong(&ccs.date, &date);
	Com_sprintf(message, sizeof(message), _("%i %s %02i"),
		date.year, Date_GetMonthName(date.month - 1), date.day);
	XML_AddString(node, SAVE_GAMEDATE, message);
	/* working through all subsystems. perhaps we should redesign it, order is not important anymore */
	Com_Printf("Calling subsystems\n");
	for (i = 0; i < saveSubsystemsAmount; i++) {
		if (!saveSubsystems[i].save(node))
			Com_Printf("...subsystem '%s' failed to save the data\n", saveSubsystems[i].name);
		else
			Com_Printf("...subsystem '%s' - saved\n", saveSubsystems[i].name);
	}

	/* calculate the needed buffer size */
	OBJZERO(header);
	header.compressed = LittleLong(save_compressed->integer);
	header.version = LittleLong(SAVE_FILE_VERSION);
	header.subsystems = LittleLong(saveSubsystemsAmount);
	Q_strncpyz(header.name, comment, sizeof(header.name));
	Q_strncpyz(header.gameVersion, UFO_VERSION, sizeof(header.gameVersion));
	CP_DateConvertLong(&ccs.date, &date);
	Com_sprintf(header.gameDate, sizeof(header.gameDate), _("%i %s %02i"),
		date.year, Date_GetMonthName(date.month - 1), date.day);
	Q_strncpyz(header.realDate, timeStampBuffer, sizeof(header.realDate));

	requiredBufferLength = mxmlSaveString(topNode, dummy, 2, MXML_NO_CALLBACK);

	header.xmlSize = LittleLong(requiredBufferLength);
	byte* const buf = Mem_PoolAllocTypeN(byte, requiredBufferLength + 1, cp_campaignPool);
	if (!buf) {
		mxmlDelete(topNode);
		*error = _("Could not allocate enough memory to save this game");
		Com_Printf("Error: Could not allocate enough memory to save this game\n");
		return false;
	}
	res = mxmlSaveString(topNode, (char*)buf, requiredBufferLength + 1, MXML_NO_CALLBACK);
	mxmlDelete(topNode);
	Com_Printf("XML Written to buffer (%d Bytes)\n", res);

	if (header.compressed)
		bufLen = compressBound(requiredBufferLength);
	else
		bufLen = requiredBufferLength;

	byte* const fbuf = Mem_PoolAllocTypeN(byte, bufLen + sizeof(header), cp_campaignPool);
	memcpy(fbuf, &header, sizeof(header));

	if (header.compressed) {
		res = compress(fbuf + sizeof(header), &bufLen, buf, requiredBufferLength);
		Mem_Free(buf);

		if (res != Z_OK) {
			Mem_Free(fbuf);
			*error = _("Memory error compressing save-game data - set save_compressed cvar to 0");
			Com_Printf("Memory error compressing save-game data (%s) (Error: %i)!\n", comment, res);
			return false;
		}
	} else {
		memcpy(fbuf + sizeof(header), buf, requiredBufferLength);
		Mem_Free(buf);
	}

	/* last step - write data */
	res = FS_WriteFile(fbuf, bufLen + sizeof(header), savegame);
	Mem_Free(fbuf);

	return true;
}
Beispiel #5
0
/**
 * @brief add a non-empty String attribute to the XML Node
 * @param[out] parent XML Node structure to add to
 * @param[in] name Name of the attribute
 * @param[in] value Value of the attribute
 * @note if the value is empty nothing will be added
 */
void XML_AddStringValue (xmlNode_t* parent, const char* name, const char* value)
{
	if (Q_strnull(value))
		return;
	XML_AddString(parent, name, value);
}