YPF

From Game Research Wiki
Jump to navigation Jump to search

Used in the following games:

  • Eroge! ~Sex and Games Make Sexy Games~

Structure

Header
Size Content Description
4Bytes Magic/ID "YPF/0"
4Bytes Unknown1 Static?
4Bytes File Count Number of Files in archive
4Bytes Index Size Size of Index
16Bytes Padding
Index Entry
Size Content Description
4Bytes Unknown1
1Bytes Filename Length XOR 0xFF, then table lookup (see below).
?Bytes Filename XOR 0xFF then XOR 0x40
2Bytes Unknown2 Static?
4Bytes FileSize1
4Bytes FileSize2 Suggests compression is supported
4Bytes File Offset
4Bytes Unknown3

Comments

To decode the filenames, each byte in the filename is XOR by 0xFF and then 0x40. However, the filenames are not null terminated so 1 byte is stored before the filename that represents the the filename's length. This value is protected like the filename but is slightly different (as far as I can tell). XOR by 0xFF and then do a table lookup. The table is generated at runtime and swaps around a number of values.

char lookup(char incoming)
{
	switch (incoming)
	{
	case 0x09:
		return 0x0B;
	case 0x0B:
		return 0x09;
	case 0x0C:
		return 0x10;
	case 0x0D:
		return 0x13;
	case 0x10:
		return 0x0C;
	case 0x11:
		return 0x19;
	case 0x13:
		return 0x0D;
	case 0x15:
		return 0x1B;
	case 0x19:
		return 0x11;
	case 0x1B:
		return 0x15;
	case 0x1C:
		return 0x1E;
	case 0x1E:
		return 0x1C;
	case 0x20:
		return 0x23;
	case 0x23:
		return 0x20;
	case 0x26:
		return 0x29;
	case 0x29:
		return 0x26;
	case 0x2C:
		return 0x2F;
	case 0x2E:
		return 0x32;
	case 0x2F:
		return 0x2C;
	case 0x32:
		return 0x2E;
	default:
		return incoming;
	}
}

ToDo: Figure out what the unknown values are for repacking function.