Skip to content

Instantly share code, notes, and snippets.

@ifarbod
Created February 3, 2017 14:55
Show Gist options
  • Save ifarbod/fb0a022c5eabeaef316a10665b126a6c to your computer and use it in GitHub Desktop.
Save ifarbod/fb0a022c5eabeaef316a10665b126a6c to your computer and use it in GitHub Desktop.
#include <Windows.h>
#include <iostream>
#include <string>
#include <cstdint>
#include <vector>
#include <tchar.h>
#include <stdio.h>
struct IplInstEntry
{
uint32_t dwModelId;
std::string sModelName;
uint32_t dwInterior;
float fX;
float fY;
float fZ;
float fQ1;
float fQ2;
float fQ3;
float fQ4;
uint32_t dwLodIndex;
};
struct IplEnexEntry
{
float fEnterX;
float fEnterY;
float fEnterZ;
float fEnterAngle;
float fWidthX;
float fWidthY;
uint32_t dwConstant8;
float fExitX;
float fExitY;
float fExitZ;
float fExitAngle;
uint32_t dwTargetInterior;
uint32_t dwEnexFlags;
std::string szEnexName;
uint32_t dwSkyColour;
uint32_t dwUnkFlags;
uint32_t dwTimeOn;
uint32_t dwTimeOff;
};
struct IplGrgeEntry
{
float fBottomRightX;
float fBottomRightY;
float fBottomRightZ;
float fFrontX;
float fFrontY;
float fUpperLeftX;
float fUpperLeftY;
float fUpperLeftZ;
uint32_t dwGrgxFlags;
uint32_t dwUnused;
std::string szGrgxName;
uint32_t dwNumCars;
uint32_t dwGrgxType;
uint32_t dwDoorStyle;
};
struct IdeObjsEntry
{
uint32_t dwModel;
std::string szDffName;
std::string szTxdName;
uint32_t dwDrawDistance;
uint32_t dwFlags;
};
static void ProcessFile(const char* pFileName);
static void ProcessFileMode2();
static IplInstEntry ms_IplInstEntries[4096];
static IplEnexEntry ms_IplEnexEntries[4096];
static IplGrgeEntry ms_IplGrgeEntries[4096];
static IdeObjsEntry ms_IdeObjsEntries[4096];
static bool ms_ShouldSkipEnexEntry[4096];
static bool ms_ShouldSkipInstEntry[4096];
static bool ms_ShouldSkipGrgeEntry[4096];
static bool bHasLodInIde[4096];
static int ms_NumberOfIplInstEntries = 0;
static int ms_NumberOfIplEnexEntries = 0;
static int ms_NumberOfIplGrgeEntries = 0;
static int ms_NumberOfIdeObjsEntries = 0;
static int ms_CurrentIndexInTextIpl = 0;
static int ms_CurrentIndexInBinIPL = 0;
static int ms_LodIndex = 0;
static int ms_ArrayIndex = 0;
static int ms_ToolMode = 0;
int main()
{
HANDLE hFiles;
WIN32_FIND_DATAA data;
std::cout << "-------------------------------\n";
std::cout << "IPL Optimizer by dkluin\n";
std::cout << "This tool is meant to move all LOD indexed instances to a binary IPL.\n";
std::cout << "Version 3.0\n";
std::cout << "-------------------------------\n";
std::cout << "Select a mode:\n";
std::cout << "1 | Sort IPL into binary and text IPL\n";
std::cout << "2 | Use input.ide file in input folder to give output.ipl LOD entries from IDE\n";
std::cin >> ms_ToolMode;
switch (ms_ToolMode)
{
// Process ipl to binary/lod ipl
case 1:
{
if (CreateDirectoryA("input", NULL))
{
std::cout << "Created missing input directory!\n";
}
if (CreateDirectoryA("output", NULL))
{
std::cout << "Created missing output directory!\n";
}
hFiles = FindFirstFileA("input\\*", &data);
if (hFiles != INVALID_HANDLE_VALUE)
{
while (FindNextFileA(hFiles, &data) != 0)
{
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
}
else
{
ProcessFile(data.cFileName);
}
}
FindClose(hFiles);
}
std::cout << "Done!\n";
system("pause");
exit(0);
break;
}
// Add LOD entries to output.ipl using input.ide and input.ipl
case 2:
{
if (CreateDirectoryA("input", NULL))
{
std::cout << "Created missing input directory!\n";
}
if (CreateDirectoryA("output", NULL))
{
std::cout << "Created missing output directory!\n";
}
// Process input.ide
ProcessFileMode2();
std::cout << "Done!\n";
system("pause");
exit(0);
break;
}
}
return 0;
}
enum IplSections
{
IPL_SECTION_NONE = 0,
IPL_SECTION_INST,
IPL_SECTION_CARS,
IPL_SECTION_GRGE,
IPL_SECTION_PICK,
IPL_SECTION_ENEX
};
void ProcessFileMode2()
{
FILE* pSourceIDE = fopen("input\\input.ide", "r");
FILE* pSourceIPL = fopen("input\\input.ipl", "r");
FILE* pDestIpl = fopen("output\\output.ipl", "w");
IplInstEntry currInstEntry;
IdeObjsEntry currObjsEntry;
uint8_t ms_IplSection = IPL_SECTION_NONE;
char Buffer[512];
char szModelName[128];
char szDffNamee[128];
char szTxdNamee[128];
std::string szLODModel;
bool bInObjs = false;
memset(&currInstEntry, NULL, sizeof(IplInstEntry));
memset(&currObjsEntry, NULL, sizeof(IdeObjsEntry));
memset(ms_IplInstEntries, NULL, sizeof(ms_IplInstEntries));
ms_NumberOfIplInstEntries = 0;
szModelName[0] = NULL;
if (pSourceIPL)
{
// Read line
while (fgets(Buffer, sizeof(Buffer), pSourceIPL))
{
for (int i = 0; i < 512; i++)
{
if (Buffer[i] == ',' || Buffer[i] == '"')
{
Buffer[i] = ' ';
}
}
if (Buffer[0] == '#' || !Buffer[0])
continue;
else
{
if (Buffer[0] == 'i' && Buffer[1] == 'n' && Buffer[2] == 's' && Buffer[3] == 't')
{
ms_IplSection = IPL_SECTION_INST;
continue;
}
if (ms_IplSection == IPL_SECTION_INST)
{
if (Buffer[0] == 'e' && Buffer[1] == 'n' && Buffer[2] == 'd')
{
ms_IplSection = IPL_SECTION_NONE;
continue;
}
else
{
sscanf(Buffer, "%d %s %d %f %f %f %f %f %f %f %d", &currInstEntry.dwModelId, &szModelName, &currInstEntry.dwInterior, &currInstEntry.fX, &currInstEntry.fY, &currInstEntry.fZ, &currInstEntry.fQ1,
&currInstEntry.fQ2, &currInstEntry.fQ3, &currInstEntry.fQ4, &currInstEntry.dwLodIndex);
//printf("Reading inst line: %d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", currInstEntry.dwModelId, &currInstEntry.sModelName, currInstEntry.dwInterior, currInstEntry.fX, currInstEntry.fY, currInstEntry.fZ, currInstEntry.fQ1, currInstEntry.fQ2, currInstEntry.fQ3, currInstEntry.fQ4, currInstEntry.dwLodIndex);
// Print the LOD entry (if it has one!)
ms_IplInstEntries[ms_NumberOfIplInstEntries].dwModelId = currInstEntry.dwModelId;
ms_IplInstEntries[ms_NumberOfIplInstEntries].sModelName = szModelName;
ms_IplInstEntries[ms_NumberOfIplInstEntries].dwInterior = currInstEntry.dwInterior;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fX = currInstEntry.fX;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fY = currInstEntry.fY;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fZ = currInstEntry.fZ;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ1 = currInstEntry.fQ1;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ2 = currInstEntry.fQ2;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ3 = currInstEntry.fQ3;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ4 = currInstEntry.fQ4;
ms_IplInstEntries[ms_NumberOfIplInstEntries].dwLodIndex = currInstEntry.dwLodIndex;
ms_ShouldSkipInstEntry[ms_NumberOfIplInstEntries] = false;
ms_NumberOfIplInstEntries++;
}
}
}
}
}
fclose(pSourceIPL);
// Read text IDE
if (pSourceIDE)
{
while (fgets(Buffer, sizeof(Buffer), pSourceIPL))
{
for (int i = 0; i < 512; i++)
{
if (Buffer[i] == ',' || Buffer[i] == '"')
{
Buffer[i] = ' ';
}
}
if (Buffer[0] == '#' || !Buffer[0])
continue;
else
{
if (Buffer[0] == 'o' && Buffer[1] == 'b' && Buffer[2] == 'j' && Buffer[3] == 's')
{
bInObjs = true;
continue;
}
if (bInObjs)
{
if (Buffer[0] == 'e' && Buffer[1] == 'n' && Buffer[2] == 'd')
{
bInObjs = false;
continue;
}
else
{
sscanf(Buffer, "%d %s %s %d %d", &currObjsEntry.dwModel, &szDffNamee, &szTxdNamee, &currObjsEntry.dwDrawDistance, &currObjsEntry.dwFlags);
// Store objs entries
ms_IdeObjsEntries[ms_NumberOfIdeObjsEntries].dwModel = currObjsEntry.dwModel;
ms_IdeObjsEntries[ms_NumberOfIdeObjsEntries].szDffName = szDffNamee;
ms_IdeObjsEntries[ms_NumberOfIdeObjsEntries].szTxdName = szTxdNamee;
ms_IdeObjsEntries[ms_NumberOfIdeObjsEntries].dwDrawDistance = currObjsEntry.dwDrawDistance;
ms_IdeObjsEntries[ms_NumberOfIdeObjsEntries].dwFlags = currObjsEntry.dwFlags;
ms_NumberOfIdeObjsEntries++;
}
}
}
}
}
fclose(pSourceIDE);
if (pDestIpl)
{
fprintf(pDestIpl, "#######################################################################################################\n");
fprintf(pDestIpl, "################################ COPYRIGHT GTA: UNDERGROUND ################################\n");
fprintf(pDestIpl, "################################ ################################\n");
fprintf(pDestIpl, "################################ Processed by dkluin's IPL sorter ################################\n");
fprintf(pDestIpl, "#######################################################################################################\n");
//fprintf(pDestIpl, "# %s - created on %d-%d-%d %02d:%02d\n", pFileName, ms_SysTime.wDay, ms_SysTime.wMonth, ms_SysTime.wYear, ms_SysTime.wHour, ms_SysTime.wMinute);
fprintf(pDestIpl, "inst\n");
if (ms_NumberOfIplInstEntries)
{
for (int i = 0; i < ms_NumberOfIplInstEntries; i++)
{
szLODModel = ms_IplInstEntries[i].sModelName;
szLODModel.erase(0, 3);
szLODModel = "LOD" + szLODModel;
// There is! Print the line as if it had a LOD and then break.
// Print a model with LOD below it - there is a lod!
fprintf(pDestIpl, "%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", ms_IplInstEntries[i].dwModelId, ms_IplInstEntries[i].sModelName.c_str(),
ms_IplInstEntries[i].dwInterior, ms_IplInstEntries[i].fX, ms_IplInstEntries[i].fY, ms_IplInstEntries[i].fZ, ms_IplInstEntries[i].fQ1,
ms_IplInstEntries[i].fQ2, ms_IplInstEntries[i].fQ3, ms_IplInstEntries[i].fQ4, ms_LodIndex + 1);
fprintf(pDestIpl, "%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", ms_IplInstEntries[i].dwModelId, szLODModel.c_str(), ms_IplInstEntries[i].dwInterior, ms_IplInstEntries[i].fX,
ms_IplInstEntries[i].fY, ms_IplInstEntries[i].fZ,
ms_IplInstEntries[i].fQ1, ms_IplInstEntries[i].fQ2, ms_IplInstEntries[i].fQ3, ms_IplInstEntries[i].fQ4, -1);
ms_LodIndex += 2;
}
}
fprintf(pDestIpl, "end\n");
}
fclose(pDestIpl);
}
void ProcessFile(const char* pFileName)
{
std::string szInputFile;
std::string szOutputFileText;
std::string szOutputFileBin;
size_t ms_PosOfIpl[2];
SYSTEMTIME ms_SysTime;
uint8_t ms_IplSection = IPL_SECTION_NONE;
IplInstEntry currInstEntry;
IplEnexEntry currEnexEntry;
IplGrgeEntry currGrgeEntry;
GetLocalTime(&ms_SysTime);
szInputFile = pFileName;
szOutputFileText = pFileName;
ms_PosOfIpl[0] = szInputFile.find(".ipl");
ms_PosOfIpl[1] = szOutputFileText.find(".ipl");
if (ms_PosOfIpl)
{
szInputFile.erase(ms_PosOfIpl[0], 4);
szOutputFileText.erase(ms_PosOfIpl[1], 4);
}
szOutputFileText = "output\\" + szOutputFileText;
szOutputFileText += ".ipl";
szOutputFileBin = szInputFile;
szOutputFileBin = "output\\" + szOutputFileBin;
szOutputFileBin += "_stream0.ipl";
szInputFile = "input\\" + szInputFile;
szInputFile += ".ipl";
printf("Opening file: %s\n", szInputFile.c_str());
FILE* pSource = fopen(szInputFile.c_str(), "r");
FILE* pDestText = fopen(szOutputFileText.c_str(), "w");
FILE* pDestBin = fopen(szOutputFileBin.c_str(), "w");
char Buffer[512];
bool has_lod_entry = false;
char szModelName[128];
char szEnexNamee[128];
char szGrgeName[128];
szModelName[0] = NULL;
szEnexNamee[0] = NULL;
szGrgeName[0] = NULL;
size_t ms_NumOfEntriesRead[2];
ms_NumOfEntriesRead[0] = NULL;
ms_NumOfEntriesRead[1] = NULL;
memset(&currInstEntry, NULL, sizeof(IplInstEntry));
memset(&currEnexEntry, NULL, sizeof(IplEnexEntry));
memset(&currGrgeEntry, NULL, sizeof(IplGrgeEntry));
memset(ms_IplInstEntries, NULL, sizeof(ms_IplInstEntries));
memset(ms_IplEnexEntries, NULL, sizeof(ms_IplEnexEntries));
memset(ms_IplGrgeEntries, NULL, sizeof(ms_IplGrgeEntries));
ms_NumberOfIplInstEntries = 0;
ms_NumberOfIplEnexEntries = 0;
ms_NumberOfIplGrgeEntries = 0;
ms_CurrentIndexInTextIpl = 0;
ms_CurrentIndexInBinIPL = 0;
ms_LodIndex = 0;
ms_ArrayIndex = 0;
if (pSource)
{
// Read line
while (fgets(Buffer, sizeof(Buffer), pSource))
{
for (int i = 0; i < 512; i++)
{
if (Buffer[i] == ',' || Buffer[i] == '"')
{
Buffer[i] = ' ';
}
}
if (Buffer[0] == '#' || !Buffer[0])
continue;
else
{
if (Buffer[0] == 'i' && Buffer[1] == 'n' && Buffer[2] == 's' && Buffer[3] == 't')
{
ms_IplSection = IPL_SECTION_INST;
continue;
}
if (Buffer[0] == 'e' && Buffer[1] == 'n' && Buffer[2] == 'e' && Buffer[3] == 'x')
{
ms_IplSection = IPL_SECTION_ENEX;
continue;
}
if (Buffer[0] == 'g' && Buffer[1] == 'r' && Buffer[2] == 'g' && Buffer[3] == 'e')
{
ms_IplSection = IPL_SECTION_GRGE;
continue;
}
if (ms_IplSection == IPL_SECTION_GRGE)
{
if (Buffer[0] == 'e' && Buffer[1] == 'n' && Buffer[2] == 'd')
{
ms_IplSection = IPL_SECTION_NONE;
continue;
}
else
{
if (sscanf(Buffer, "%f %f %f %f %f %f %f %f %d %d %s %d %d %d", &currGrgeEntry.fBottomRightX, &currGrgeEntry.fBottomRightY, &currGrgeEntry.fBottomRightZ, &currGrgeEntry.fFrontX, &currGrgeEntry.fFrontY,
&currGrgeEntry.fUpperLeftX, &currGrgeEntry.fUpperLeftY, &currGrgeEntry.fUpperLeftZ, &currGrgeEntry.dwGrgxFlags, &currGrgeEntry.dwUnused, &szGrgeName, &currGrgeEntry.dwNumCars,
&currGrgeEntry.dwGrgxType, &currGrgeEntry.dwDoorStyle) == -1)
{
ms_ShouldSkipGrgeEntry[ms_NumberOfIplGrgeEntries] = true;
ms_NumberOfIplGrgeEntries++;
}
else
{
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fBottomRightX = currGrgeEntry.fBottomRightX;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fBottomRightY = currGrgeEntry.fBottomRightY;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fBottomRightZ = currGrgeEntry.fBottomRightZ;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fFrontX = currGrgeEntry.fFrontX;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fFrontY = currGrgeEntry.fFrontY;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fUpperLeftX = currGrgeEntry.fUpperLeftX;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fUpperLeftY = currGrgeEntry.fUpperLeftY;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].fUpperLeftZ = currGrgeEntry.fUpperLeftZ;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].dwGrgxFlags = currGrgeEntry.dwGrgxFlags;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].dwUnused = currGrgeEntry.dwUnused;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].szGrgxName = szGrgeName;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].dwNumCars = currGrgeEntry.dwNumCars;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].dwGrgxType = currGrgeEntry.dwGrgxType;
ms_IplGrgeEntries[ms_NumberOfIplGrgeEntries].dwDoorStyle = currGrgeEntry.dwDoorStyle;
ms_ShouldSkipGrgeEntry[ms_NumberOfIplGrgeEntries] = false;
ms_NumberOfIplGrgeEntries++;
}
}
}
if (ms_IplSection == IPL_SECTION_ENEX)
{
if (Buffer[0] == 'e' && Buffer[1] == 'n' && Buffer[2] == 'd')
{
ms_IplSection = IPL_SECTION_NONE;
continue;
}
else
{
if (sscanf(Buffer, "%f %f %f %f %f %f %d %f %f %f %f %d %d %s %d %d %d %d", &currEnexEntry.fEnterX, &currEnexEntry.fEnterY, &currEnexEntry.fEnterZ, &currEnexEntry.fEnterAngle, &currEnexEntry.fWidthX,
&currEnexEntry.fWidthY, &currEnexEntry.dwConstant8, &currEnexEntry.fExitX, &currEnexEntry.fExitY, &currEnexEntry.fExitZ, &currEnexEntry.fExitAngle, &currEnexEntry.dwTargetInterior, &currEnexEntry.dwEnexFlags,
&szEnexNamee, &currEnexEntry.dwSkyColour, &currEnexEntry.dwUnkFlags, &currEnexEntry.dwTimeOn, &currEnexEntry.dwTimeOff) == -1)
{
ms_ShouldSkipEnexEntry[ms_NumberOfIplEnexEntries] = true;
ms_NumberOfIplEnexEntries++;
}
else
{
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fEnterX = currEnexEntry.fEnterX;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fEnterY = currEnexEntry.fEnterY;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fEnterZ = currEnexEntry.fEnterZ;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fEnterAngle = currEnexEntry.fEnterAngle;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fWidthX = currEnexEntry.fWidthX;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fWidthY = currEnexEntry.fWidthY;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwConstant8 = currEnexEntry.dwConstant8;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fExitX = currEnexEntry.fExitX;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fExitY = currEnexEntry.fExitY;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fExitZ = currEnexEntry.fExitZ;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].fExitAngle = currEnexEntry.fExitAngle;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwTargetInterior = currEnexEntry.dwTargetInterior;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwEnexFlags = currEnexEntry.dwEnexFlags;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].szEnexName = szEnexNamee;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwSkyColour = currEnexEntry.dwSkyColour;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwUnkFlags = currEnexEntry.dwUnkFlags;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwTimeOn = currEnexEntry.dwTimeOn;
ms_IplEnexEntries[ms_NumberOfIplEnexEntries].dwTimeOff = currEnexEntry.dwTimeOff;
ms_ShouldSkipEnexEntry[ms_NumberOfIplEnexEntries] = false;
ms_NumberOfIplEnexEntries++;
}
}
}
if (ms_IplSection == IPL_SECTION_INST)
{
if (Buffer[0] == 'e' && Buffer[1] == 'n' && Buffer[2] == 'd')
{
ms_IplSection = IPL_SECTION_NONE;
continue;
}
else
{
sscanf(Buffer, "%d %s %d %f %f %f %f %f %f %f %d", &currInstEntry.dwModelId, &szModelName, &currInstEntry.dwInterior, &currInstEntry.fX, &currInstEntry.fY, &currInstEntry.fZ, &currInstEntry.fQ1,
&currInstEntry.fQ2, &currInstEntry.fQ3, &currInstEntry.fQ4, &currInstEntry.dwLodIndex);
//printf("Reading inst line: %d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", currInstEntry.dwModelId, &currInstEntry.sModelName, currInstEntry.dwInterior, currInstEntry.fX, currInstEntry.fY, currInstEntry.fZ, currInstEntry.fQ1, currInstEntry.fQ2, currInstEntry.fQ3, currInstEntry.fQ4, currInstEntry.dwLodIndex);
// Print the LOD entry (if it has one!)
ms_IplInstEntries[ms_NumberOfIplInstEntries].dwModelId = currInstEntry.dwModelId;
ms_IplInstEntries[ms_NumberOfIplInstEntries].sModelName = szModelName;
ms_IplInstEntries[ms_NumberOfIplInstEntries].dwInterior = currInstEntry.dwInterior;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fX = currInstEntry.fX;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fY = currInstEntry.fY;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fZ = currInstEntry.fZ;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ1 = currInstEntry.fQ1;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ2 = currInstEntry.fQ2;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ3 = currInstEntry.fQ3;
ms_IplInstEntries[ms_NumberOfIplInstEntries].fQ4 = currInstEntry.fQ4;
ms_IplInstEntries[ms_NumberOfIplInstEntries].dwLodIndex = currInstEntry.dwLodIndex;
ms_ShouldSkipInstEntry[ms_NumberOfIplInstEntries] = false;
ms_NumberOfIplInstEntries++;
}
}
}
}
}
ms_IplSection = IPL_SECTION_NONE;
// Find all entries with LOD indexes and save them to the file
if (pDestText && pDestBin)
{
// Print IPL header in text IPL
fprintf(pDestText, "#######################################################################################################\n");
fprintf(pDestText, "################################ COPYRIGHT GTA: UNDERGROUND ################################\n");
fprintf(pDestText, "################################ ################################\n");
fprintf(pDestText, "################################ Processed by dkluin's IPL sorter ################################\n");
fprintf(pDestText, "#######################################################################################################\n");
fprintf(pDestText, "# %s - created on %d-%d-%d %02d:%02d\n", pFileName, ms_SysTime.wDay, ms_SysTime.wMonth, ms_SysTime.wYear, ms_SysTime.wHour, ms_SysTime.wMinute);
fprintf(pDestText, "inst\n");
fprintf(pDestBin, "inst\n");
if (ms_NumberOfIplInstEntries)
{
for (int i = 0; i < ms_NumberOfIplInstEntries; i++)
{
//fprintf("%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", ms_IplInstEntries[i].dwModelId, ms_IplInstEntries[i].sModelName.c_str(), ms_IplInstEntries[i].dwInterior, ms_IplInstEntries[i].fX, ms_IplInstEntries[i].fY, ms_IplInstEntries[i].fZ, ms_IplInstEntries[i].fQ1, ms_IplInstEntries[i].fQ2, ms_IplInstEntries[i].fQ3, ms_IplInstEntries[i].fQ4, ms_IplInstEntries[i].dwLodIndex);
if (ms_IplInstEntries[i].dwLodIndex != -1)
{
// Update all normal models
ms_LodIndex = ms_IplInstEntries[i].dwLodIndex;
ms_IplInstEntries[i].dwLodIndex = ms_CurrentIndexInBinIPL;
fprintf(pDestBin, "%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", ms_IplInstEntries[i].dwModelId, ms_IplInstEntries[i].sModelName.c_str(), ms_IplInstEntries[i].dwInterior, ms_IplInstEntries[i].fX, ms_IplInstEntries[i].fY, ms_IplInstEntries[i].fZ, ms_IplInstEntries[i].fQ1, ms_IplInstEntries[i].fQ2, ms_IplInstEntries[i].fQ3, ms_IplInstEntries[i].fQ4, ms_CurrentIndexInTextIpl);
// Update all LODs
fprintf(pDestText, "%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", ms_IplInstEntries[ms_LodIndex].dwModelId, ms_IplInstEntries[ms_LodIndex].sModelName.c_str(), ms_IplInstEntries[ms_LodIndex].dwInterior, ms_IplInstEntries[ms_LodIndex].fX, ms_IplInstEntries[ms_LodIndex].fY, ms_IplInstEntries[ms_LodIndex].fZ, ms_IplInstEntries[ms_LodIndex].fQ1, ms_IplInstEntries[ms_LodIndex].fQ2, ms_IplInstEntries[ms_LodIndex].fQ3, ms_IplInstEntries[ms_LodIndex].fQ4, ms_IplInstEntries[ms_LodIndex].dwLodIndex);
ms_CurrentIndexInBinIPL++;
ms_CurrentIndexInTextIpl++;
}
else
{
if (ms_IplInstEntries[i].sModelName.find("LOD") == std::string::npos)
{
ms_LodIndex = ms_IplInstEntries[i].dwLodIndex;
ms_IplInstEntries[i].dwLodIndex = -1;
fprintf(pDestBin, "%d, %s, %d, %f, %f, %f, %f, %f, %f, %f, %d\n", ms_IplInstEntries[i].dwModelId, ms_IplInstEntries[i].sModelName.c_str(), ms_IplInstEntries[i].dwInterior, ms_IplInstEntries[i].fX, ms_IplInstEntries[i].fY, ms_IplInstEntries[i].fZ, ms_IplInstEntries[i].fQ1, ms_IplInstEntries[i].fQ2, ms_IplInstEntries[i].fQ3, ms_IplInstEntries[i].fQ4, ms_IplInstEntries[i].dwLodIndex);
ms_CurrentIndexInBinIPL++;
}
}
}
}
fprintf(pDestText, "end\n");
fprintf(pDestBin, "end\n");
// If IPL had enex entries...
if (ms_NumberOfIplEnexEntries)
{
fprintf(pDestText, "enex\n");
// Copy paste them in!
for (int i = 0; i < ms_NumberOfIplEnexEntries; i++)
{
if (ms_ShouldSkipEnexEntry[i] == false)
{
fprintf(pDestText, "%f, %f, %f, %f, %f, %f, %d, %f, %f, %f, %f, %d, %d, \"%s\", %d, %d, %d, %d\n", ms_IplEnexEntries[i].fEnterX, ms_IplEnexEntries[i].fEnterY, ms_IplEnexEntries[i].fEnterZ, ms_IplEnexEntries[i].fEnterAngle, ms_IplEnexEntries[i].fWidthX,
ms_IplEnexEntries[i].fWidthY, ms_IplEnexEntries[i].dwConstant8, ms_IplEnexEntries[i].fExitX, ms_IplEnexEntries[i].fExitY, ms_IplEnexEntries[i].fExitZ, ms_IplEnexEntries[i].fExitAngle, ms_IplEnexEntries[i].dwTargetInterior, ms_IplEnexEntries[i].dwEnexFlags,
ms_IplEnexEntries[i].szEnexName.c_str(), ms_IplEnexEntries[i].dwSkyColour, ms_IplEnexEntries[i].dwUnkFlags, ms_IplEnexEntries[i].dwTimeOn, ms_IplEnexEntries[i].dwTimeOff);
}
else
{
fprintf(pDestText, "\n");
ms_ShouldSkipEnexEntry[i] = false;
}
}
fprintf(pDestText, "end\n");
}
// If IPL had grge entries...
if (ms_NumberOfIplGrgeEntries)
{
fprintf(pDestText, "grge\n");
// Copy paste them in!
for (int i = 0; i < ms_NumberOfIplGrgeEntries; i++)
{
if (ms_ShouldSkipGrgeEntry[i] == false)
{
fprintf(pDestText, "%f, %f, %f, %f, %f, %f, %f, %f, %d, %d, %s, %d, %d, %d\n", ms_IplGrgeEntries[i].fBottomRightX, ms_IplGrgeEntries[i].fBottomRightY, ms_IplGrgeEntries[i].fBottomRightZ, ms_IplGrgeEntries[i].fFrontX, ms_IplGrgeEntries[i].fFrontY,
ms_IplGrgeEntries[i].fUpperLeftX, ms_IplGrgeEntries[i].fUpperLeftY, ms_IplGrgeEntries[i].fUpperLeftZ, ms_IplGrgeEntries[i].dwGrgxFlags, ms_IplGrgeEntries[i].dwUnused, ms_IplGrgeEntries[i].szGrgxName.c_str(), ms_IplGrgeEntries[i].dwNumCars,
ms_IplGrgeEntries[i].dwGrgxType, ms_IplGrgeEntries[i].dwDoorStyle);
}
else
{
fprintf(pDestText, "\n");
ms_ShouldSkipGrgeEntry[i] = false;
}
}
fprintf(pDestText, "end\n");
}
fclose(pSource);
fclose(pDestText);
fclose(pDestBin);
}
printf("Processed input file %s\n", szInputFile.c_str());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment