Created
February 3, 2017 14:55
-
-
Save ifarbod/fb0a022c5eabeaef316a10665b126a6c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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