macrosoft3dpinball/SpaceCadetPinball/GroupData.h
type-two b671975742 Vendor SpaceCadetPinball, build for Apple Silicon
Reverse-engineered reimplementation of 3D Pinball for Windows - Space Cadet
from k4zmu2a/SpaceCadetPinball (MIT), upstream cb9b7b8, vendored rather than
submoduled so local patches are just edits.

- CMakeLists: stop hard-setting CMAKE_OSX_ARCHITECTURES so the documented -D
  override works; brew's SDL2 is arm64-only and universal linking failed.
- gitignore original .DAT/.MID assets, which are not ours to redistribute.
- CLAUDE.md: build line, upstream deviation, and where game data goes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 19:05:12 +10:00

129 lines
2.6 KiB
C++

#pragma once
struct zmap_header_type;
struct gdrv_bitmap8;
enum class FieldTypes : int16_t
{
// One 16 bit signed integer
ShortValue = 0,
// Sprite bitmap, 8bpp, indexed color
Bitmap8bit = 1,
Unknown2 = 2,
// Group name, char[]. Not all groups have names.
GroupName = 3,
Unknown4 = 4,
// Palette, contains 256 RBGA 4-byte colors.
Palette = 5,
Unknown6 = 6,
Unknown7 = 7,
Unknown8 = 8,
// String, char[]
String = 9,
// Array of 16 bit signed integers
ShortArray = 10,
// Array of 32 bit floats
FloatArray = 11,
// Sprite depth map, 16bpp, unsigned
Bitmap16bit = 12,
};
struct EntryData
{
EntryData() = default;
EntryData(FieldTypes entryType, char* buffer): EntryType(entryType), FieldSize(-1), Buffer(buffer)
{
}
~EntryData();
FieldTypes EntryType{};
int FieldSize{};
char* Buffer{};
};
#pragma pack(push, 1)
struct MsgFontChar
{
uint8_t Width;
char Data[1];
};
struct MsgFont
{
int16_t GapWidth;
int16_t Unknown1;
int16_t Height;
uint8_t CharWidths[128];
MsgFontChar Data[1];
};
#pragma pack(pop)
static_assert(sizeof(MsgFont) == 136, "Wrong size of MsgFont");
class GroupData
{
public:
int GroupId;
std::string GroupName;
GroupData(int groupId);
void AddEntry(EntryData* entry);
void FinalizeGroup();
const std::vector<EntryData*>& GetEntries() const { return Entries; }
const EntryData* GetEntry(size_t index) const { return Entries[index]; }
size_t EntryCount() const { return Entries.size(); }
void ReserveEntries(size_t count) { Entries.reserve(count); }
gdrv_bitmap8* GetBitmap(int resolution) const;
zmap_header_type* GetZMap(int resolution) const;
private:
std::vector<EntryData*> Entries;
gdrv_bitmap8* Bitmaps[3]{};
zmap_header_type* ZMaps[3]{};
bool NeedsSort = false;
static void SplitSplicedBitmap(const gdrv_bitmap8& srcBmp, gdrv_bitmap8& bmp, zmap_header_type& zMap);
void SetBitmap(gdrv_bitmap8* bmp);
void SetZMap(zmap_header_type* zMap);
};
class DatFile
{
public:
std::string AppName;
std::string Description;
std::vector<GroupData*> Groups;
~DatFile();
char* field_nth(int groupIndex, FieldTypes targetEntryType, int skipFirstN);
char* field(int groupIndex, FieldTypes entryType);
int field_size_nth(int groupIndex, FieldTypes targetEntryType, int skipFirstN);
int field_size(int groupIndex, FieldTypes targetEntryType);
int record_labeled(LPCSTR targetGroupName);
char* field_labeled(LPCSTR lpString, FieldTypes fieldType);
gdrv_bitmap8* GetBitmap(int groupIndex);
zmap_header_type* GetZMap(int groupIndex);
void Finalize();
private:
void AddMsgFont(MsgFont* font, const std::string& fontName);
};