Example #1
0
int main()
{
	char* sourcePath = openGMFFile();
	char* outputPath = saveGMFFile();
	source = fopen(sourcePath, "rb");
	output = fopen(outputPath, "w");
	
	if (source == 0 || output == 0)
	{
		printf("No file selected, exiting.");
		return 1;
	}
	
	char *header = getBytes(3);
	
	if(strncmp(header, "GMI", 3))
	{
		printf("This is not a valid binary GMF file!\n");
		return 1;
	}
	
	printf("Decompiling GMI...\n\n");

	delete header;

	int gmfVersion = getInteger();
	
	fprintf(output, "GMA\n");
	fprintf(output, "*GABRIEL_ASCIIEXPORT\t%i\n", gmfVersion);
	while(!feof(source))
	{
		char* objectType = getBytesNF(8);
		
		// Model Type
		if (!memcmp(objectType, "\x01\x00\x00\x00\x00\x00\x00\x00", 8) || !memcmp(objectType, "\x03\x00\x00\x00\x00\x00\x00\x00", 8) || !memcmp(objectType, "\x02\x00\x00\x00\x00\x00\x00\x00", 8))
		{
			if (!memcmp(objectType, "\x03\x00\x00\x00\x00\x00\x00\x00", 8) || !memcmp(objectType, "\x02\x00\x00\x00\x00\x00\x00\x00", 8))
				isRA1 = 1;
			else
				isRA1 = 0;
			getBytes(8);
			int type = getInteger();
			
			if (type == 15)
			{
				fprintf(output, "*MODEL_TYPE\tBasic Model\n");
			}
			else
			{
				printf("Unknown Model Type: %d\n", type);
				return 1;
			}
		}

		// Scene Info
		else if (!memcmp(objectType, "\x01\x00\x00\x00\x02\x00\x00\x00", 8))
		{
			readSceneInfo();
		}
		
		// Material Info
		else if (!memcmp(objectType, "\x07\x00\x00\x00\x02\x00\x00\x00", 8))
		{
			readMaterialList(0);
			
		}
		
		//Object List
		else if (!memcmp(objectType, "\x12\x00\x00\x00\x02\x00\x00\x00", 8))
		{
			readObjectList(0);			
		}
		else
		{
			getBytes(8);
			if (fgetc(source) == EOF)
				break;
			printf("Object type unknown!\n");
			debugHex(objectType, 8);
			MessageBox(NULL, "Error! Unknown Object Type!\n","Decompilation unsuccessfull!", MB_OK | MB_ICONWARNING);
			return 1;
		}
	}
	printf("Decompiled sucessfully!\n");
	MessageBox(NULL, "Binary GMF decompiled sucessfully!" ,"Decompilation successfull!", MB_OK);
	return 0;
}
Example #2
0
GeometryPtr LoaderDFF::readGeometry(const RWBStream &stream) {
    auto geomStream = stream.getInnerStream();

    auto geomStructID = geomStream.getNextChunk();
    if (geomStructID != CHUNK_STRUCT) {
        throw DFFLoaderException("Geometry missing struct chunk");
    }

    auto geom = std::make_shared<Geometry>();

    char *headerPtr = geomStream.getCursor();

    geom->flags = *(std::uint16_t *)headerPtr;
    headerPtr += sizeof(std::uint16_t);

    /*unsigned short numUVs = *(std::uint8_t*)headerPtr;*/
    headerPtr += sizeof(std::uint8_t);
    /*unsigned short moreFlags = *(std::uint8_t*)headerPtr;*/
    headerPtr += sizeof(std::uint8_t);

    unsigned int numTris = *(std::uint32_t *)headerPtr;
    headerPtr += sizeof(std::uint32_t);
    unsigned int numVerts = *(std::uint32_t *)headerPtr;
    headerPtr += sizeof(std::uint32_t);
    /*unsigned int numFrames = *(std::uint32_t*)headerPtr;*/
    headerPtr += sizeof(std::uint32_t);

    std::vector<GeometryVertex> verts;
    verts.resize(numVerts);

    if (geomStream.getChunkVersion() < 0x1003FFFF) {
        headerPtr += sizeof(RW::BSGeometryColor);
    }

    /// @todo extract magic numbers.

    if ((geom->flags & 8) == 8) {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].colour = *(glm::u8vec4 *)headerPtr;
            headerPtr += sizeof(glm::u8vec4);
        }
    } else {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].colour = {255, 255, 255, 255};
        }
    }

    if ((geom->flags & 4) == 4 || (geom->flags & 128) == 128) {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].texcoord = *(glm::vec2 *)headerPtr;
            headerPtr += sizeof(glm::vec2);
        }
    }

    // Grab indicies data to generate normals (if applicable).
    RW::BSGeometryTriangle *triangles = (RW::BSGeometryTriangle *)headerPtr;
    headerPtr += sizeof(RW::BSGeometryTriangle) * numTris;

    geom->geometryBounds = *(RW::BSGeometryBounds *)headerPtr;
    geom->geometryBounds.radius = std::abs(geom->geometryBounds.radius);
    headerPtr += sizeof(RW::BSGeometryBounds);

    for (size_t v = 0; v < numVerts; ++v) {
        verts[v].position = *(glm::vec3 *)headerPtr;
        headerPtr += sizeof(glm::vec3);
    }

    if ((geom->flags & 16) == 16) {
        for (size_t v = 0; v < numVerts; ++v) {
            verts[v].normal = *(glm::vec3 *)headerPtr;
            headerPtr += sizeof(glm::vec3);
        }
    } else {
        // Use triangle data to calculate normals for each vert.
        for (size_t t = 0; t < numTris; ++t) {
            auto &triangle = triangles[t];
            auto &A = verts[triangle.first];
            auto &B = verts[triangle.second];
            auto &C = verts[triangle.third];
            auto normal = glm::normalize(
                glm::cross(C.position - A.position, B.position - A.position));
            A.normal = normal;
            B.normal = normal;
            C.normal = normal;
        }
    }

    // Process the geometry child sections
    for (auto chunkID = geomStream.getNextChunk(); chunkID != 0;
         chunkID = geomStream.getNextChunk()) {
        switch (chunkID) {
            case CHUNK_MATERIALLIST:
                readMaterialList(geom, geomStream);
                break;
            case CHUNK_EXTENSION:
                readGeometryExtension(geom, geomStream);
                break;
            default:
                break;
        }
    }

    geom->dbuff.setFaceType(geom->facetype == Geometry::Triangles
                                ? GL_TRIANGLES
                                : GL_TRIANGLE_STRIP);
    geom->gbuff.uploadVertices(verts);
    geom->dbuff.addGeometry(&geom->gbuff);

    glGenBuffers(1, &geom->EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geom->EBO);

    size_t icount = std::accumulate(
        geom->subgeom.begin(), geom->subgeom.end(), 0u,
        [](size_t a, const SubGeometry &b) { return a + b.numIndices; });
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * icount, 0,
                 GL_STATIC_DRAW);
    for (auto &sg : geom->subgeom) {
        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, sg.start * sizeof(uint32_t),
                        sizeof(uint32_t) * sg.numIndices, sg.indices.data());
    }

    return geom;
}
Example #3
0
int decompile(HWND parent, const LPWSTR sourcePath, const LPWSTR outputPath)
{
	isRA1 = 0;
	_wfopen_s(&source, sourcePath, L"rb");
	_wfopen_s(&output, outputPath, L"w");
	
	if (source == 0 || output == 0)
	{
		myprintf("No file selected.");
		return 1;
	}
	
	char *header = getBytes(3);
	
	if(strncmp(header, "GMI", 3))
	{
		myprintf("This is not a valid binary GMF file!\n");
		return 1;
	}
	free(header);
	
	myprintf("Decompiling GMI...\n\n");


	int gmfVersion = getInteger();
	
	fprintf(output, "GMA\n");
	fprintf(output, "*GABRIEL_ASCIIEXPORT\t%i\n", gmfVersion);
	while(!feof(source))
	{
		char* objectType = getBytesNF(8);
		
		// Model Type
		if (!memcmp(objectType, "\x01\x00\x00\x00\x00\x00\x00\x00", 8) || !memcmp(objectType, "\x03\x00\x00\x00\x00\x00\x00\x00", 8) || !memcmp(objectType, "\x02\x00\x00\x00\x00\x00\x00\x00", 8))
		{
			if (!memcmp(objectType, "\x03\x00\x00\x00\x00\x00\x00\x00", 8) || !memcmp(objectType, "\x02\x00\x00\x00\x00\x00\x00\x00", 8))
				isRA1 = 1;
			else
				isRA1 = 0;
			free(getBytes(8));
			int type = getInteger();
			
			if (type == 15)
			{
				fprintf(output, "*MODEL_TYPE\tBasic Model\n");
			}
			else
			{
				myprintf("Unknown Model Type: %d\n", type);
				return 1;
			}
		}

		// Scene Info
		else if (!memcmp(objectType, "\x01\x00\x00\x00\x02\x00\x00\x00", 8))
		{
			readSceneInfo();
		}
		
		// Material Info
		else if (!memcmp(objectType, "\x07\x00\x00\x00\x02\x00\x00\x00", 8))
		{
			readMaterialList(0);
			
		}
		
		//Object List
		else if (!memcmp(objectType, "\x12\x00\x00\x00\x02\x00\x00\x00", 8))
		{
			readObjectList(0);			
		}
		else
		{
			free(getBytes(8));
			if (fgetc(source) == EOF)
				break;
			myprintf("Object type unknown!\n");
			debugHex(objectType, 8);
			MessageBox(parent, L"Error! Unknown Object Type!\n",L"Decompilation unsuccessfull!", MB_OK | MB_ICONWARNING);
			free(objectType);
			return 1;
		}

		free(objectType);
	}
	myprintf("Decompiled sucessfully!\n");
	MessageBox(parent, L"Binary GMF decompiled sucessfully!" ,L"Decompilation successfull!", MB_OK);
	fclose(source);
	fclose(output);
	return 0;
}
int readMaterial()
{
	printInt(8);
	printInt(2);

	//Placeholder for length
	printBytes("\xFF\xFF\xFF\xFF", 4);

	int beginningOffset = ftell(output);

	readNothing("*MATERIAL");

	openBracket();

	int matRefNo = readInt("*MATERIAL_REF_NO");
	char* matName = readString("*MATERIAL_NAME");
	char* matClass = readString("*MATERIAL_CLASS");
	char* matAmbient = readRGB("*MATERIAL_AMBIENT");
	char* matDiffuse = readRGB("*MATERIAL_DIFFUSE");
	char* matSpecular = readRGB("*MATERIAL_SPECULAR");
	float matShine = readFloat("*MATERIAL_SHINE");
	float matShineStrength = readFloat("*MATERIAL_SHINESTRENGTH");
	float matTransparency = readFloat("*MATERIAL_TRANSPARENCY");
	/*float matTransparency;
	bracketize();
	char* buffer = (char*) malloc(sizeof(char)* 24);
	int offset = ftell(input);*/
	float matWireSize = readFloat("*MATERIAL_WIRESIZE");
	char* matShading = readString("*MATERIAL_SHADING");
	float matXPFallof = readFloat("*MATERIAL_XP_FALLOF");
	float matSelfIllum = readFloat("*MATERIAL_SELFILLUM");
	char* matFallof = readString("*MATERIAL_FALLOF");
	char* matXPType = readString("*MATERIAL_XP_TYPE");

	printInt(matRefNo);
	printString(matName);
	printString(matClass);
	printBytes(matAmbient, 4);
	printBytes(matDiffuse, 4);
	printBytes(matSpecular, 4);
	printFloat(matShine);
	printFloat(matShineStrength);
	printFloat(matTransparency);
	printFloat(matWireSize);

	if(!strncmp(matShading, "Blinn", 5))
		printInt(12);
	else
		printInt(0);

	printFloat(matXPFallof);
	printFloat(matSelfIllum);

	if(!strncmp(matFallof, "In", 2))
		printInt(1);
	else
		printInt(0);

	if(!strncmp(matXPType, "Filter", 6))
		printInt(1);
	else
		printInt(0);

	char* nextType = (char*)malloc(sizeof(char)*32);

	int numMaterials = 0;
	int numTextures = 0;

	int tParsed = 0;
	int mParsed = 0;

	while(1)
	{
		int currentOffset = ftell(input);
		fscanf(input, "%s\n", nextType);
		if(!strncmp(nextType, "*TEXTURE_LIST", 14) && tParsed == 0)
		{
			//Placeholder for number of textures
			int numTexturesOffset = ftell(output);
			printBytes("\xDE\xAD\xBE\xEF", 4);

			numTextures += readTextureList();

			int afterTextureList = ftell(output);
			fseek(output, numTexturesOffset, 0);
			printInt(numTextures);
			fseek(output, afterTextureList, 0);
			mParsed = 1;
		}
		else if(tParsed == 0)
		{
			tParsed = 1;
			printInt(0);
		}

		if(!strncmp(nextType, "*MATERIAL_LIST", 14) && mParsed == 0)
		{
			//Placeholder for number of textures
			int numMaterialsOffset = ftell(output);
			printBytes("\xDE\xAD\xBE\xEF", 4);

			numMaterials += readMaterialList();

			int afterMaterialList = ftell(output);
			fseek(output, numMaterialsOffset, 0);
			printInt(numMaterials);
			fseek(output, afterMaterialList, 0);
			mParsed = 1;
		}
		else if (mParsed == 0)
		{
			mParsed = 1;
			printInt(0);
		}		
		
		if(!strncmp(nextType, "}", 1))
		{
			fseek(input, currentOffset, 0);
			break;
		}
	}

	closeBracket();

	int endOffset = ftell(output);
	int size = endOffset - beginningOffset;

	fseek(output, beginningOffset - 4, 0);
	
	printInt(size);

	fseek(output, endOffset, 0);

	return 0;
}