mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-22 17:00:18 +01:00
Partman v2, ready.
This commit is contained in:
parent
375db278c4
commit
7d141d2931
5 changed files with 391 additions and 54 deletions
|
@ -23,4 +23,28 @@
|
|||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="datFileStruct">
|
||||
<DisplayString>{{ NumberOfGroups={NumberOfGroups} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[NumberOfGroups]" ExcludeView="simple">NumberOfGroups</Item>
|
||||
<Item Name="[Description]" ExcludeView="simple">Description</Item>
|
||||
<ArrayItems>
|
||||
<Size>NumberOfGroups</Size>
|
||||
<ValuePointer>GroupData</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
<Type Name="datGroupData">
|
||||
<DisplayString>{{ EntryCount={EntryCount} }}</DisplayString>
|
||||
<Expand>
|
||||
<Item Name="[EntryCount]" ExcludeView="simple">EntryCount</Item>
|
||||
<ArrayItems>
|
||||
<Size>EntryCount</Size>
|
||||
<ValuePointer>Entries</ValuePointer>
|
||||
</ArrayItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
|
||||
</AutoVisualizer>
|
|
@ -2,6 +2,7 @@
|
|||
//
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <iostream>
|
||||
#include "objlist_class.h"
|
||||
#include "partman.h"
|
||||
|
@ -23,6 +24,19 @@ int main()
|
|||
char dataFileName[300];
|
||||
partman::make_path_name(dataFileName, "PINBALL.DAT");
|
||||
auto datFile = partman::load_records(dataFileName);
|
||||
assert(datFile);
|
||||
|
||||
assert(partman::field_size_nth(datFile, 0, String, 0) == 43);
|
||||
assert(partman::field_size_nth(datFile, 2, Palette, 0) == 1024);
|
||||
assert(partman::field_size_nth(datFile, 101, FloatArray, 4) == 32);
|
||||
|
||||
assert(strcmp(partman::field(datFile, 0, String), "3D-Pinball: Copyright 1994, Cinematronics") == 0);
|
||||
assert(strcmp(partman::field(datFile, 540, GroupName), "table_objects") == 0);
|
||||
|
||||
assert(partman::record_labeled(datFile, "background") == 2);
|
||||
assert(partman::record_labeled(datFile, "a_bump1") == 372);
|
||||
|
||||
assert(memcmp(partman::field_labeled(datFile, "table_size", ShortArray), new short[2]{ 600, 416 }, 2 * 2) == 0);
|
||||
|
||||
//DatParser::Parse(dataFileName);
|
||||
}
|
||||
|
|
|
@ -1,80 +1,324 @@
|
|||
#include "pch.h"
|
||||
#include "partman.h"
|
||||
|
||||
short partman::_field_size[] = { 2, 0x0FFFF, 2, 0x0FFFF, 0x0FFFF, 0x0FFFF, 0x0FFFF, 0x0FFFF,0x0FFFF, 0x0FFFF, 0x0FFFF, 0x0FFFF, 0x0FFFF, 0 };
|
||||
short partman::_field_size[] = {
|
||||
2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
|
||||
};
|
||||
|
||||
|
||||
datFileStruct* partman::load_records(LPCSTR lpFileName)
|
||||
{
|
||||
_OFSTRUCT ReOpenBuff{};
|
||||
datFileHeader Buffer;
|
||||
datFileHeader Buffer{};
|
||||
dat8BitBmpHeader bmpHeader{};
|
||||
datFileStruct* datFile;
|
||||
HFILE fileHandle, hFile;
|
||||
int lenOfStr, groupIndex;
|
||||
unsigned short unknown;
|
||||
char* descriptionBuf, * unknownBuf, * unknownBuf2;
|
||||
char** groupDataBuf;
|
||||
int groupIndex, groupDataSize;
|
||||
datGroupData** groupDataBuf;
|
||||
|
||||
fileHandle = OpenFile(lpFileName, &ReOpenBuff, 0);
|
||||
hFile = fileHandle;
|
||||
const HFILE fileHandle = OpenFile(lpFileName, &ReOpenBuff, 0);
|
||||
if (fileHandle == -1)
|
||||
return 0;
|
||||
return nullptr;
|
||||
_lread(fileHandle, &Buffer, 183u);
|
||||
if (lstrcmpA("PARTOUT(4.0)RESOURCE", Buffer.FileSignature))
|
||||
{
|
||||
_lclose(fileHandle);
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
datFile = (datFileStruct*)memoryallocate(10);
|
||||
datFile = (datFileStruct*)memoryallocate(sizeof(datFileStruct));
|
||||
if (!datFile)
|
||||
{
|
||||
_lclose(fileHandle);
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
if (lstrlenA(Buffer.Description) <= 0)
|
||||
{
|
||||
datFile->Description = 0;
|
||||
datFile->Description = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
lenOfStr = lstrlenA(Buffer.Description);
|
||||
descriptionBuf = (char*)memoryallocate(lenOfStr + 1);
|
||||
int lenOfStr = lstrlenA(Buffer.Description);
|
||||
auto descriptionBuf = (char*)memoryallocate(lenOfStr + 1);
|
||||
datFile->Description = descriptionBuf;
|
||||
if (!descriptionBuf)
|
||||
{
|
||||
_lclose(fileHandle);
|
||||
LABEL_10:
|
||||
memoryfree(datFile);
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
lstrcpyA(descriptionBuf, Buffer.Description);
|
||||
}
|
||||
unknown = Buffer.Unknown;
|
||||
|
||||
if (Buffer.Unknown)
|
||||
{
|
||||
unknownBuf = (char*)memoryallocate(Buffer.Unknown);
|
||||
unknownBuf2 = unknownBuf;
|
||||
auto unknownBuf = (char*)memoryallocate(Buffer.Unknown);
|
||||
if (!unknownBuf)
|
||||
{
|
||||
_lclose(hFile);
|
||||
goto LABEL_19;
|
||||
_lclose(fileHandle);
|
||||
if (datFile->Description)
|
||||
memoryfree(datFile->Description);
|
||||
memoryfree(datFile);
|
||||
return nullptr;
|
||||
}
|
||||
_lread(hFile, (void*)unknownBuf, unknown);
|
||||
memoryfree(unknownBuf2);
|
||||
_lread(fileHandle, static_cast<void*>(unknownBuf), Buffer.Unknown);
|
||||
memoryfree(unknownBuf);
|
||||
}
|
||||
groupDataBuf = (char**)memoryallocate(4 * Buffer.NumberOfGroups);
|
||||
|
||||
groupDataBuf = (datGroupData**)memoryallocate(sizeof(void*) * Buffer.NumberOfGroups);
|
||||
datFile->GroupData = groupDataBuf;
|
||||
if (!groupDataBuf)
|
||||
{
|
||||
LABEL_19:
|
||||
if (datFile->Description)
|
||||
memoryfree(datFile->Description);
|
||||
goto LABEL_10;
|
||||
memoryfree(datFile);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
groupIndex = 0;
|
||||
if (Buffer.NumberOfGroups)
|
||||
{
|
||||
do
|
||||
{
|
||||
char entryCount = _lread_char(fileHandle);
|
||||
if (entryCount <= 0)
|
||||
groupDataSize = 0;
|
||||
else
|
||||
groupDataSize = entryCount - 1;
|
||||
datFile->GroupData[groupIndex] = (datGroupData*)memoryallocate(
|
||||
sizeof(datEntryData) * groupDataSize + sizeof(datGroupData));
|
||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
||||
if (!groupData)
|
||||
break;
|
||||
int entryIndex = 0;
|
||||
groupData->EntryCount = entryCount;
|
||||
if (entryCount > 0)
|
||||
{
|
||||
datEntryData* entryData = groupData->Entries;
|
||||
do
|
||||
{
|
||||
auto entryType = static_cast<datFieldTypes>(_lread_char(fileHandle));
|
||||
entryData->EntryType = entryType;
|
||||
int fieldSize = _field_size[entryType];
|
||||
if (fieldSize < 0)
|
||||
{
|
||||
fieldSize = _lread_long(fileHandle);
|
||||
}
|
||||
if (entryType == Bitmap8bit)
|
||||
{
|
||||
_hread(fileHandle, &bmpHeader, 14);
|
||||
char* bmpBuffer = (char*)memoryallocate(0x25u);
|
||||
entryData->Buffer = bmpBuffer;
|
||||
if (!bmpBuffer)
|
||||
goto LABEL_41;
|
||||
/*if (bmpHeader.Unknown2 & 2 ? gdrv_create_bitmap((int)bmpBuffer, bmpHeader.Width, bmpHeader.Height) : gdrv_create_raw_bitmap((int)bmpBuffer, bmpHeader.Width, bmpHeader.Height, bmpHeader.Unknown2 & 1))
|
||||
goto LABEL_41;*/
|
||||
//_hread(fileHandle, *(LPVOID*)(entryData->Buffer + 8), bmpHeader.Size);
|
||||
char* tempBuff = (char*)memoryallocate(bmpHeader.Size);
|
||||
_hread(fileHandle, tempBuff, bmpHeader.Size);
|
||||
memoryfree(tempBuff);
|
||||
*((int*)entryData->Buffer + 29) = bmpHeader.XPosition;
|
||||
*((int*)entryData->Buffer + 33) = bmpHeader.YPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
char* entryBuffer = (char*)memoryallocate(fieldSize);
|
||||
entryData->Buffer = entryBuffer;
|
||||
if (!entryBuffer)
|
||||
goto LABEL_41;
|
||||
_hread(fileHandle, entryBuffer, fieldSize);
|
||||
}
|
||||
|
||||
++entryIndex;
|
||||
entryData->FieldSize = fieldSize;
|
||||
datFile->NumberOfGroups = groupIndex + 1;
|
||||
++entryData;
|
||||
}
|
||||
while (entryIndex < entryCount);
|
||||
}
|
||||
++groupIndex;
|
||||
}
|
||||
while (groupIndex < Buffer.NumberOfGroups);
|
||||
}
|
||||
|
||||
LABEL_41:
|
||||
_lclose(fileHandle);
|
||||
if (datFile->NumberOfGroups == Buffer.NumberOfGroups)
|
||||
return datFile;
|
||||
unload_records(datFile);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
return datFile;
|
||||
void partman::unload_records(datFileStruct* datFile)
|
||||
{
|
||||
for (int groupIndex = 0; groupIndex < datFile->NumberOfGroups; ++groupIndex)
|
||||
{
|
||||
datGroupData* group = datFile->GroupData[groupIndex];
|
||||
if (group)
|
||||
{
|
||||
int entryIndex = 0;
|
||||
if (group->EntryCount > 0)
|
||||
{
|
||||
datEntryData* entry = group->Entries;
|
||||
do
|
||||
{
|
||||
if (entry->Buffer)
|
||||
{
|
||||
//if (HIWORD(entry->EntryType) == 1)
|
||||
//gdrv_destroy_bitmap(entry->Buffer);
|
||||
memoryfree(entry->Buffer);
|
||||
}
|
||||
++entryIndex;
|
||||
++entry;
|
||||
}
|
||||
while (entryIndex < group->EntryCount);
|
||||
}
|
||||
memoryfree(group);
|
||||
}
|
||||
}
|
||||
if (datFile->Description)
|
||||
memoryfree(datFile->Description);
|
||||
memoryfree(datFile->GroupData);
|
||||
memoryfree(datFile);
|
||||
}
|
||||
|
||||
char* partman::field(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType)
|
||||
{
|
||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
||||
int entryCount = groupData->EntryCount;
|
||||
int entryIndex = 0;
|
||||
if (entryCount <= 0)
|
||||
return nullptr;
|
||||
datEntryData* entry = groupData->Entries;
|
||||
while (true)
|
||||
{
|
||||
int entryType = entry->EntryType;
|
||||
if (entryType == targetEntryType)
|
||||
break;
|
||||
if (entryType > targetEntryType)
|
||||
return nullptr;
|
||||
++entryIndex;
|
||||
++entry;
|
||||
if (entryIndex < entryCount)
|
||||
continue;
|
||||
return nullptr;
|
||||
}
|
||||
return entry->Buffer;
|
||||
}
|
||||
|
||||
|
||||
char* partman::field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN)
|
||||
{
|
||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
||||
int entryCount = groupData->EntryCount, skipCount = 0, entryIndex = 0;
|
||||
if (0 < entryCount)
|
||||
{
|
||||
datEntryData* entry = groupData->Entries;
|
||||
do
|
||||
{
|
||||
int entryType = entry->EntryType;
|
||||
if (entryType == targetEntryType)
|
||||
{
|
||||
if (skipCount == skipFirstN)
|
||||
{
|
||||
return entry->Buffer;
|
||||
}
|
||||
skipCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetEntryType < entryType)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
entryIndex++;
|
||||
entry++;
|
||||
}
|
||||
while (entryIndex < entryCount);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int partman::field_size_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN)
|
||||
{
|
||||
datGroupData* groupData = datFile->GroupData[groupIndex];
|
||||
int entryCount = groupData->EntryCount, skipCount = 0, entryIndex = 0;
|
||||
if (0 < entryCount)
|
||||
{
|
||||
datEntryData* entry = groupData->Entries;
|
||||
do
|
||||
{
|
||||
int entryType = entry->EntryType;
|
||||
if (entryType == targetEntryType)
|
||||
{
|
||||
if (skipCount == skipFirstN)
|
||||
{
|
||||
return entry->FieldSize;
|
||||
}
|
||||
skipCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetEntryType < entryType)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
entryIndex++;
|
||||
entry++;
|
||||
}
|
||||
while (entryIndex < entryCount);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int partman::field_size(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType)
|
||||
{
|
||||
return field_size_nth(datFile, groupIndex, targetEntryType, 0);
|
||||
}
|
||||
|
||||
int partman::record_labeled(datFileStruct* datFile, LPCSTR targetGroupName)
|
||||
{
|
||||
int trgGroupNameLen = lstrlenA(targetGroupName);
|
||||
int groupIndex = datFile->NumberOfGroups;
|
||||
while (true)
|
||||
{
|
||||
if (--groupIndex < 0)
|
||||
return -1;
|
||||
char* groupName = field(datFile, groupIndex, GroupName);
|
||||
if (groupName)
|
||||
{
|
||||
int index = 0;
|
||||
bool found = trgGroupNameLen == 0;
|
||||
if (trgGroupNameLen > 0)
|
||||
{
|
||||
LPCSTR targetNamePtr = targetGroupName;
|
||||
do
|
||||
{
|
||||
if (*targetNamePtr != targetNamePtr[groupName - targetGroupName])
|
||||
break;
|
||||
++index;
|
||||
++targetNamePtr;
|
||||
}
|
||||
while (index < trgGroupNameLen);
|
||||
found = index == trgGroupNameLen;
|
||||
}
|
||||
if (found && !targetGroupName[index] && !groupName[index])
|
||||
break;
|
||||
}
|
||||
}
|
||||
return groupIndex;
|
||||
}
|
||||
|
||||
char* partman::field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType)
|
||||
{
|
||||
char* result;
|
||||
int groupIndex = record_labeled(datFile, lpString);
|
||||
if (groupIndex < 0)
|
||||
result = nullptr;
|
||||
else
|
||||
result = field(datFile, groupIndex, fieldType);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,3 +344,17 @@ int partman::make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize)
|
|||
lstrcatA(lpFilename, "?");
|
||||
return 1;
|
||||
}
|
||||
|
||||
char partman::_lread_char(HFILE hFile)
|
||||
{
|
||||
char Buffer = 0;
|
||||
_lread(hFile, &Buffer, 1u);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
int partman::_lread_long(HFILE hFile)
|
||||
{
|
||||
int Buffer = 0;
|
||||
_lread(hFile, &Buffer, 4u);
|
||||
return Buffer;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
enum datFieldTypes : __int16
|
||||
{
|
||||
ShortValue = 0,
|
||||
//, does not have the 32bits size value, but a 16bits value(see above).
|
||||
Bitmap8bit = 1,
|
||||
// 8 bpp bitmap
|
||||
Unknown2 = 2,
|
||||
GroupName = 3,
|
||||
// Group name
|
||||
Unknown4 = 4,
|
||||
Palette = 5,
|
||||
// Palette(1 color is 1 DWORD, only present 1 time in PINBALL.DAT ,with a data size of 1024 bytes for 256 colors.Some colors are 0 ,because their indexes are reserved by Windows.)
|
||||
Unknown6 = 6,
|
||||
Unknown7 = 7,
|
||||
Unknown8 = 8,
|
||||
String = 9,
|
||||
// String(content)
|
||||
ShortArray = 10,
|
||||
// Array of 16bits integer values
|
||||
FloatArray = 11,
|
||||
// Array of 32bits floating point values(collision box, ...)
|
||||
Bitmap16bit = 12,
|
||||
// 16 bpp bitmap(Heightmap ? )
|
||||
};
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct datFileHeader
|
||||
struct datFileHeader
|
||||
{
|
||||
char FileSignature[21];
|
||||
char AppName[50];
|
||||
|
@ -15,44 +40,60 @@ struct datFileHeader
|
|||
#pragma pack(pop)
|
||||
static_assert(sizeof(datFileHeader) == 183, "Wrong size of datFileHeader");
|
||||
|
||||
struct datEntryData
|
||||
{
|
||||
datFieldTypes EntryType;
|
||||
int FieldSize;
|
||||
char* Buffer;
|
||||
};
|
||||
|
||||
struct datGroupData
|
||||
{
|
||||
__int16 EntryCount;
|
||||
datEntryData Entries[1];
|
||||
};
|
||||
|
||||
struct datFileStruct
|
||||
{
|
||||
unsigned short NumberOfGroups;
|
||||
char* Description;
|
||||
char** GroupData;
|
||||
datGroupData** GroupData;
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum datFieldTypes
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
struct dat8BitBmpHeader
|
||||
{
|
||||
ShortValue = 0,//, does not have the 32bits size value, but a 16bits value(see above).
|
||||
Bitmap8bit = 1,// 8 bpp bitmap
|
||||
Unknown2 = 2,
|
||||
GroupName = 3,// Group name
|
||||
Unknown4 = 4,
|
||||
Palette = 5,// Palette(1 color is 1 DWORD, only present 1 time in PINBALL.DAT ,with a data size of 1024 bytes for 256 colors.Some colors are 0 ,because their indexes are reserved by Windows.)
|
||||
Unknown6 = 6,
|
||||
Unknown7 = 7,
|
||||
Unknown8 = 8,
|
||||
String = 9,// String(content)
|
||||
ShortArray = 10,// Array of 16bits integer values
|
||||
FloatArray = 11,// Array of 32bits floating point values(collision box, ...)
|
||||
Bitmap16bit = 12,// 16 bpp bitmap(Heightmap ? )
|
||||
char Unknown1;
|
||||
__int16 Width;
|
||||
__int16 Height;
|
||||
__int16 XPosition;
|
||||
__int16 YPosition;
|
||||
int Size;
|
||||
char Unknown2;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(dat8BitBmpHeader) == 14, "Wrong size of dat8BitBmpHeader");
|
||||
|
||||
|
||||
//typedef const char* LPCSTR;
|
||||
class partman
|
||||
{
|
||||
public:
|
||||
static datFileStruct* load_records(LPCSTR lpFileName);
|
||||
static void unload_records(datFileStruct* datFile);
|
||||
static char* field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN);
|
||||
static char* field(datFileStruct* datFile, int groupIndex, datFieldTypes entryType);
|
||||
static int field_size_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN);
|
||||
static int field_size(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType);
|
||||
static int record_labeled(datFileStruct* datFile, LPCSTR targetGroupName);
|
||||
static char* field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType);
|
||||
|
||||
static int make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize = 0x12Cu);
|
||||
|
||||
private:
|
||||
static short _field_size[];
|
||||
static char _lread_char(HFILE hFile);
|
||||
static int _lread_long(HFILE hFile);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
// TODO: add headers that you want to pre-compile here
|
||||
#include <windows.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <assert.h>
|
||||
|
||||
#define memoryallocate(x) malloc(x);
|
||||
#define memoryfree(x) free(x);
|
||||
|
|
Loading…
Reference in a new issue