Example #1
0
/**
 * Save a chunk of data.
 * @param fp The file to save to.
 * @param header The chunk identification string (4 chars, always).
 * @param saveProc The proc to call to generate the content of the chunk.
 * @return True if and only if all bytes were written successful.
 */
static bool Save_Chunk(FILE *fp, char *header, bool (*saveProc)(FILE *fp))
{
	uint32 position;
	uint32 length;
	uint32 lengthSwapped;

	if (fwrite(header, 4, 1, fp) != 1) return false;

	/* Reserve the length field */
	length = 0;
	if (fwrite(&length, 4, 1, fp) != 1) return false;

	/* Store the content of the chunk, and remember the length */
	position = ftell(fp);
	if (!saveProc(fp)) return false;
	length = ftell(fp) - position;

	/* Ensure we are word aligned */
	if ((length & 1) == 1) {
		uint8 empty = 0;
		if (fwrite(&empty, 1, 1, fp) != 1) return false;
	}

	/* Write back the chunk size */
	fseek(fp, position - 4, SEEK_SET);
	lengthSwapped = HTOBE32(length);
	if (fwrite(&lengthSwapped, 4, 1, fp) != 1) return false;
	fseek(fp, 0, SEEK_END);

	return true;
}
Example #2
0
static void FillSavegameDesc(bool save)
{
	uint8 i;

	for (i = 0; i < 5; i++) {
		char *desc = g_savegameDesc[i];
		char *filename;
		uint8 fileId;

		*desc = '\0';

		if (s_savegameIndexBase - i < 0) continue;

		if (s_savegameIndexBase - i == s_savegameCountOnDisk) {
			if (!save) continue;

			strncpy(desc, String_Get_ByIndex(STR_EMPTY_SLOT_), 50);
			continue;
		}

		filename = GenerateSavegameFilename(s_savegameIndexBase - i);

		if (!File_Exists(filename)) continue;

		fileId = ChunkFile_Open(filename);
		ChunkFile_Read(fileId, HTOBE32(CC_NAME), desc, 50);
		ChunkFile_Close(fileId);
		continue;
	}
}
Example #3
0
/**
 * Seek to the given chunk inside a chunk file.
 *
 * @param index The index given by ChunkFile_Open() of the file.
 * @param chunk The chunk to seek to.
 * @return The length of the chunk (0 if not found).
 */
uint32 ChunkFile_Seek(uint8 index, uint32 chunk)
{
	uint32 value = 0;
	uint32 length = 0;
	bool first = true;

	while (true) {
		if (File_Read(index, &value, 4) != 4 && !first) return 0;

		if (value == 0 && File_Read(index, &value, 4) != 4 && !first) return 0;

		if (File_Read(index, &length, 4) != 4 && !first) return 0;

		length = HTOBE32(length);

		if (value == chunk) {
			File_Seek(index, -8, 1);
			return length;
		}

		if (first) {
			File_Seek(index, 12, 0);
			first = false;
			continue;
		}

		length += 1;
		length &= 0xFFFFFFFE;
		File_Seek(index, length, 1);
	}
}
void
psbuf_put_4(struct puffs_framebuf *pb, uint32_t val)
{
	int rv;

	HTOBE32(val);
	rv = puffs_framebuf_putdata(pb, &val, 4);
	CHECK(rv == 0);
}
Example #5
0
/**
 * Save the game for real. It creates all the required chunks and stores them
 *  to the file. It updates the field lengths where needed.
 *
 * @param fp The file to save to.
 * @param description The description of the savegame.
 * @return True if and only if all bytes were written successful.
 */
static bool Save_Main(FILE *fp, char *description)
{
	uint32 length;
	uint32 lengthSwapped;

	/* Write the 'FORM' chunk (in which all other chunks are) */
	if (fwrite("FORM", 4, 1, fp) != 1) return false;
	/* Write zero length for now. We come back to this value before closing */
	length = 0;
	if (fwrite(&length, 4, 1, fp) != 1) return false;

	/* Write the 'SCEN' chunk. Never contains content. */
	if (fwrite("SCEN", 4, 1, fp) != 1) return false;

	/* Write the 'NAME' chunk. Keep ourself word-aligned. */
	if (fwrite("NAME", 4, 1, fp) != 1) return false;
	length = min(255, strlen(description) + 1);
	lengthSwapped = HTOBE32(length);
	if (fwrite(&lengthSwapped, 4, 1, fp) != 1) return false;
	if (fwrite(description, length, 1, fp) != 1) return false;
	/* Ensure we are word aligned */
	if ((length & 1) == 1) {
		uint8 empty = 0;
		if (fwrite(&empty, 1, 1, fp) != 1) return false;
	}

	/* Store all additional chunks */
	if (!Save_Chunk(fp, "INFO", &Info_Save)) return false;
	if (!Save_Chunk(fp, "PLYR", &House_Save)) return false;
	if (!Save_Chunk(fp, "UNIT", &Unit_Save)) return false;
	if (!Save_Chunk(fp, "BLDG", &Structure_Save)) return false;
	if (!Save_Chunk(fp, "MAP ", &Map_Save)) return false;
	if (!Save_Chunk(fp, "TEAM", &Team_Save)) return false;

	/* Write the total length of all data in the FORM chunk */
	length = ftell(fp) - 8;
	fseek(fp, 4, SEEK_SET);
	lengthSwapped = HTOBE32(length);
	if (fwrite(&lengthSwapped, 4, 1, fp) != 1) return false;

	return true;
}
Example #6
0
static void GUI_Mentat_LoadHelpSubjects(bool init)
{
    static uint8 *helpDataList = NULL;

    uint8 fileID;
    uint32 length;
    uint32 counter;
    uint8 *helpSubjects;
    uint16 i;

    if (init) {
        helpDataList = GFX_Screen_Get_ByIndex(SCREEN_1);

        s_topHelpList = 0;
        s_selectedHelpSubject = 0;

        sprintf(s_mentatFilename, "MENTAT%c", g_table_houseInfo[g_playerHouseID].name[0]);
        strncpy(s_mentatFilename, String_GenerateFilename(s_mentatFilename), sizeof(s_mentatFilename));
    }

    fileID = ChunkFile_Open(s_mentatFilename);
    length = ChunkFile_Read(fileID, HTOBE32(CC_NAME), helpDataList, GFX_Screen_GetSize_ByIndex(SCREEN_1));
    ChunkFile_Close(fileID);

    s_numberHelpSubjects = 0;
    helpSubjects = helpDataList;

    counter = 0;
    while (counter < length) {
        uint8 size = *helpSubjects;

        counter += size;

        if (helpSubjects[size - 1] > g_campaignID + 1) {
            while (size-- != 0) *helpSubjects++ = '\0';
            continue;
        }

        helpSubjects[size - 1] = size;
        helpSubjects += size;
        s_numberHelpSubjects++;
    }

    helpSubjects = helpDataList;

    while (*helpSubjects == '\0') helpSubjects++;

    for (i = 0; i < s_topHelpList; i++) helpSubjects = String_NextString(helpSubjects);

    s_helpSubjects = helpSubjects;
}
Example #7
0
/**
 * Open a chunk file (starting with FORM) for reading.
 *
 * @param filename The name of the file to open.
 * @return An index value refering to the opened file, or FILE_INVALID.
 */
uint8 ChunkFile_Open(const char *filename)
{
	uint8 index;
	uint32 header;

	index = File_Open(filename, 1);
	File_Close(index);

	index = File_Open(filename, 1);

	File_Read(index, &header, 4);

	if (header != HTOBE32('FORM')) {
		File_Close(index);
		return FILE_INVALID;
	}

	File_Seek(index, 4, 1);

	return index;
}
Example #8
0
/**
 * Read bytes from a chunk file into a buffer.
 *
 * @param index The index given by ChunkFile_Open() of the file.
 * @param chunk The chunk to read from.
 * @param buffer The buffer to read into.
 * @param length The amount of bytes to read.
 * @return The amount of bytes truly read, or 0 if there was a failure.
 */
uint32 ChunkFile_Read(uint8 index, uint32 chunk, void *buffer, uint32 buflen)
{
	uint32 value = 0;
	uint32 length = 0;
	bool first = true;

	while (true) {
		if (File_Read(index, &value, 4) != 4 && !first) return 0;

		if (value == 0 && File_Read(index, &value, 4) != 4 && !first) return 0;

		if (File_Read(index, &length, 4) != 4 && !first) return 0;

		length = HTOBE32(length);

		if (value == chunk) {
			buflen = min(buflen, length);

			File_Read(index, buffer, buflen);

			length += 1;
			length &= 0xFFFFFFFE;

			if (buflen < length) File_Seek(index, length - buflen, 1);

			return buflen;
		}

		if (first) {
			File_Seek(index, 12, 0);
			first = false;
			continue;
		}

		length += 1;
		length &= 0xFFFFFFFE;
		File_Seek(index, length, 1);
	}
}
Example #9
0
static void GUI_Mentat_ShowHelp(void)
{
    struct {
        uint8  notused[8];
        uint32 length;
    } info;
    uint8 *subject;
    uint16 i;
    bool noDesc;
    uint8 fileID;
    uint32 offset;
    char *compressedText;
    char *desc;
    char *picture;
    char *text;
    bool loc12;

    subject = s_helpSubjects;

    for (i = 0; i < s_selectedHelpSubject; i++) subject = String_NextString(subject);

    noDesc = (subject[5] == '0');
    offset = HTOBE32(*(uint32 *)(subject + 1));

    fileID = ChunkFile_Open(s_mentatFilename);
    ChunkFile_Read(fileID, HTOBE32(CC_INFO), &info, 12);
    ChunkFile_Close(fileID);

    info.length = HTOBE32(info.length);

    text = g_readBuffer;
    compressedText = GFX_Screen_Get_ByIndex(SCREEN_1);

    fileID = File_Open(s_mentatFilename, FILE_MODE_READ);
    File_Seek(fileID, offset, 0);
    File_Read(fileID, compressedText, info.length);
    String_Decompress(compressedText, text);
    String_TranslateSpecial(text, text);
    File_Close(fileID);

    while (*text != '*' && *text != '?') text++;

    loc12 = (*text == '*');

    *text++ = '\0';

    if (noDesc) {
        uint16 index;

        picture = g_scenario.pictureBriefing;
        desc    = NULL;
        text    = (char *)g_readBuffer;

        index = *text - 44 + g_campaignID * 4 + STR_HOUSE_HARKONNENFROM_THE_DARK_WORLD_OF_GIEDI_PRIME_THE_SAVAGE_HOUSE_HARKONNEN_HAS_SPREAD_ACROSS_THE_UNIVERSE_A_CRUEL_PEOPLE_THE_HARKONNEN_ARE_RUTHLESS_TOWARDS_BOTH_FRIEND_AND_FOE_IN_THEIR_FANATICAL_PURSUIT_OF_POWER + g_playerHouseID * 40;

        strncpy(g_readBuffer, String_Get_ByIndex(index), g_readBufferSize);
    } else {
        picture = (char *)g_readBuffer;
        desc    = text;

        while (*text != '\0' && *text != 0xC) text++;
        if (*text != '\0') *text++ = '\0';
    }

    GUI_Mentat_Loop(picture, desc, text, loc12 ? 1 : 0, g_widgetMentatFirst);

    GUI_Widget_MakeNormal(g_widgetMentatFirst, false);

    GUI_Mentat_LoadHelpSubjects(false);

    GUI_Mentat_Create_HelpScreen_Widgets();

    GUI_Mentat_Draw(true);
}