diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx
new file mode 100644
index 0000000..bfd49e4
Binary files /dev/null and b/Doc/FuncStats.xlsx differ
diff --git a/FuncStats.xlsx b/FuncStats.xlsx
deleted file mode 100644
index fcff112..0000000
Binary files a/FuncStats.xlsx and /dev/null differ
diff --git a/SpaceCadetPinball/SpaceCadetPinball.cpp b/SpaceCadetPinball/SpaceCadetPinball.cpp
index 2fb6f8d..ba9a1f9 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.cpp
+++ b/SpaceCadetPinball/SpaceCadetPinball.cpp
@@ -7,6 +7,7 @@
#include "objlist_class.h"
#include "partman.h"
#include "DatParser.h"
+#include "gdrv.h"
#include "loader.h"
#include "pinball.h"
#include "score.h"
@@ -18,8 +19,11 @@ int main()
std::cout << "Hello World!\n";
pinball::hinst = GetModuleHandleA(nullptr);
- char cmdLine[1];
- WinMain(pinball::hinst, 0, cmdLine, 10);
+ char cmdLine[1]{};
+ //WinMain(pinball::hinst, 0, cmdLine, 10);
+
+ auto dib = gdrv::DibCreate(8, 1, 1);
+ gdrv::DibSetUsage(dib, 0, 1);
objlist_class d = objlist_class(2, 4);
for (int i = 0; i < 100; i++)
@@ -35,17 +39,17 @@ int main()
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(partman::field_size_nth(datFile, 0, datFieldTypes::String, 0) == 43);
+ assert(partman::field_size_nth(datFile, 2, datFieldTypes::Palette, 0) == 1024);
+ assert(partman::field_size_nth(datFile, 101, datFieldTypes::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(strcmp(partman::field(datFile, 0, datFieldTypes::String), "3D-Pinball: Copyright 1994, Cinematronics") == 0);
+ assert(strcmp(partman::field(datFile, 540, datFieldTypes::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);
+ assert(memcmp(partman::field_labeled(datFile, "table_size", datFieldTypes::ShortArray), new short[2]{ 600, 416 }, 2 * 2) == 0);
//loader::error(25, 26);
loader::loadfrom(datFile);
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
index c05b169..5bcbfb4 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
@@ -157,6 +157,7 @@
+
@@ -200,12 +201,14 @@
+
+
@@ -253,6 +256,7 @@
+
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
index 7b6d392..514302a 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
@@ -162,6 +162,12 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
@@ -302,6 +308,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
diff --git a/SpaceCadetPinball/TLight.h b/SpaceCadetPinball/TLight.h
index b824302..e60d80b 100644
--- a/SpaceCadetPinball/TLight.h
+++ b/SpaceCadetPinball/TLight.h
@@ -4,7 +4,7 @@ class TLight :
public TPinballComponent
{
public:
- TLight(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
+ TLight(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
{
}
};
diff --git a/SpaceCadetPinball/TPinballComponent.cpp b/SpaceCadetPinball/TPinballComponent.cpp
index 63f4344..cc777b2 100644
--- a/SpaceCadetPinball/TPinballComponent.cpp
+++ b/SpaceCadetPinball/TPinballComponent.cpp
@@ -2,6 +2,7 @@
#include "TPinballComponent.h"
#include "loader.h"
#include "objlist_class.h"
+#include "render.h"
#include "TZmapList.h"
#include "TPinballTable.h"
@@ -9,75 +10,69 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
{
visualStruct visual{}; // [esp+Ch] [ebp-6Ch]
- //this->VfTable = (int)&TPinballComponent::`vftable';
- this->MessageField = 0;
- this->UnknownBaseFlag1 = 0;
- this->UnknownBaseFlag2 = 0;
- this->PinballTable = table;
- this->Unknown7 = 0;
- this->List1Bitmap8 = nullptr;
- this->List2Bitmap16 = nullptr;
+ MessageField = 0;
+ UnknownBaseFlag1 = 0;
+ UnknownBaseFlag2 = 0;
+ PinballTable = table;
+ RenderSprite = nullptr;
+ ListBitmap = nullptr;
+ ListZMap = nullptr;
if (table)
table->ListP1->Add(this);
if (groupIndex >= 0)
- this->GroupName = loader::query_name(groupIndex);
+ GroupName = loader::query_name(groupIndex);
if (loadVisuals && groupIndex >= 0)
{
int visualCount = loader::query_visual_states(groupIndex);
for (int index = 0; index < visualCount; ++index)
{
loader::query_visual(groupIndex, index, &visual);
- if (visual.Bitmap8)
+ if (visual.Bitmap)
{
- if (!this->List1Bitmap8)
- this->List1Bitmap8 = new TZmapList(visualCount, 4);
- if (this->List1Bitmap8)
- this->List1Bitmap8->Add(visual.Bitmap8);
+ if (!ListBitmap)
+ ListBitmap = new TZmapList(visualCount, 4);
+ if (ListBitmap)
+ ListBitmap->Add(visual.Bitmap);
}
- if (visual.Bitmap16)
+ if (visual.ZMap)
{
- if (!this->List2Bitmap16)
- this->List2Bitmap16 = new TZmapList(visualCount, 4);
- if (this->List2Bitmap16)
- this->List2Bitmap16->Add(visual.Bitmap16);
+ if (!ListZMap)
+ ListZMap = new TZmapList(visualCount, 4);
+ if (ListZMap)
+ ListZMap->Add(visual.ZMap);
}
}
- if (this->List2Bitmap16)
- int listVal0 = (int)this->List2Bitmap16->Get(0);
- if (this->List1Bitmap8)
+ zmap_header_type* zMap = nullptr;
+ if (ListZMap)
+ zMap = static_cast(ListZMap->Get(0));
+ if (ListBitmap)
{
- /*listVal0_2 = (int*)this->List1Bitmap8->Get(0);
- v24 = *(int*)((char*)listVal0_2 + 29) - table->UnknownP49;
- v15 = 1;
- v25 = *(int*)((char*)listVal0_2 + 33) - table->UnknownP50;
- v26 = listVal0_2[3];
- v27 = listVal0_2[4];
- if (List1Bitmap8->Count() > 1)
+ visual_rect bmp1Rect{}, tmpRect{};
+ auto rootBmp = static_cast(ListBitmap->Get(0));
+ bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;
+ bmp1Rect.YPosition = rootBmp->YPosition - table->YOffset;
+ bmp1Rect.Width = rootBmp->Width;
+ bmp1Rect.Height = rootBmp->Height;
+ for (int index = 1; index < ListBitmap->Count(); index++)
{
- index = 12;
- do
- {
- v16 = *(int**)((char*)&this->List1Bitmap8->ListPtr->Size + index);
- v20 = *(int*)((char*)v16 + 29) - table->UnknownP49;
- v21 = *(int*)((char*)v16 + 33) - table->UnknownP50;
- v22 = v16[3];
- v23 = v16[4];
- enclosing_box(&v24, &v20, &v24);
- index += 4;
- ++v15;
- } while (v15 < this->List1Bitmap8->ListPtr->Count);
+ auto bmp = static_cast(ListBitmap->Get(index));
+ tmpRect.XPosition = bmp->XPosition - table->XOffset;
+ tmpRect.YPosition = bmp->YPosition - table->YOffset;
+ tmpRect.Width = bmp->Width;
+ tmpRect.Height = bmp->Height;
+ maths::enclosing_box(&bmp1Rect, &tmpRect, &bmp1Rect);
}
- v17 = this->List1Bitmap8->ListPtr->Array[0];
- this->Unknown7 = (int)render_create_sprite(
- visualCount > 0,
- this->List1Bitmap8->ListPtr->Array[0],
- listVal0,
- *(int*)(v17 + 29) - table->UnknownP49,
- *(int*)(v17 + 33) - table->UnknownP50,
- &v24);*/
+
+ RenderSprite = render::create_sprite(
+ visualCount > 0 ? VisualType::Sprite :VisualType::None,
+ rootBmp,
+ zMap,
+ rootBmp->XPosition - table->XOffset,
+ rootBmp->YPosition - table->YOffset,
+ &bmp1Rect);
}
}
- this->GroupIndex = groupIndex;
+ GroupIndex = groupIndex;
}
@@ -87,25 +82,25 @@ TPinballComponent::~TPinballComponent()
if (table)
table->ListP1->Delete(this);
- delete List1Bitmap8;
- delete List2Bitmap16;
+ delete ListBitmap;
+ delete ListZMap;
}
int TPinballComponent::Message(int message1, float message2)
{
- this->MessageField = message1;
+ MessageField = message1;
if (message1 == 1024)
- this->MessageField = 0;
+ MessageField = 0;
return 0;
}
-void TPinballComponent::put_scoring( int score1, int score2)
-{
+void TPinballComponent::put_scoring(int score1, int score2)
+{
}
int TPinballComponent::get_scoring(int score1)
{
return 0;
-}
\ No newline at end of file
+}
diff --git a/SpaceCadetPinball/TPinballComponent.h b/SpaceCadetPinball/TPinballComponent.h
index 434b550..42ded2f 100644
--- a/SpaceCadetPinball/TPinballComponent.h
+++ b/SpaceCadetPinball/TPinballComponent.h
@@ -1,4 +1,5 @@
#pragma once
+#include "render.h"
#include "TZmapList.h"
@@ -19,8 +20,8 @@ public:
int Unknown4;
int Unknown5;
int GroupIndex;
- int Unknown7;
+ render_sprite_type_struct* RenderSprite;
TPinballTable* PinballTable;
- TZmapList* List1Bitmap8;
- TZmapList* List2Bitmap16;
+ TZmapList* ListBitmap;
+ TZmapList* ListZMap;
};
diff --git a/SpaceCadetPinball/TPinballTable.h b/SpaceCadetPinball/TPinballTable.h
index 0c3a498..b5304da 100644
--- a/SpaceCadetPinball/TPinballTable.h
+++ b/SpaceCadetPinball/TPinballTable.h
@@ -63,8 +63,8 @@ public:
TPlunger* Plunger;
TDrain* Drain;
int UnknownP48;
- int UnknownP49;
- int UnknownP50;
+ int XOffset;
+ int YOffset;
int UnknownP51;
int UnknownP52;
objlist_class* ListP1;
diff --git a/SpaceCadetPinball/TSound.h b/SpaceCadetPinball/TSound.h
index 9f8074b..3a3a3fe 100644
--- a/SpaceCadetPinball/TSound.h
+++ b/SpaceCadetPinball/TSound.h
@@ -4,7 +4,7 @@ class TSound :
public TPinballComponent
{
public:
- TSound(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
+ TSound(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
{
}
};
diff --git a/SpaceCadetPinball/TTextBox.h b/SpaceCadetPinball/TTextBox.h
index 2a66046..bf27bcd 100644
--- a/SpaceCadetPinball/TTextBox.h
+++ b/SpaceCadetPinball/TTextBox.h
@@ -5,7 +5,7 @@ class TTextBox :
public TPinballComponent
{
public:
- TTextBox(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
+ TTextBox(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
{
}
diff --git a/SpaceCadetPinball/TTimer.h b/SpaceCadetPinball/TTimer.h
index 985e43b..6ed87a1 100644
--- a/SpaceCadetPinball/TTimer.h
+++ b/SpaceCadetPinball/TTimer.h
@@ -4,7 +4,7 @@ class TTimer :
public TPinballComponent
{
public:
- TTimer(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, false)
+ TTimer(TPinballTable* table, int groupIndex) : TPinballComponent(table, groupIndex, true)
{
}
};
diff --git a/SpaceCadetPinball/gdrv.cpp b/SpaceCadetPinball/gdrv.cpp
index 846ea09..5d7ab17 100644
--- a/SpaceCadetPinball/gdrv.cpp
+++ b/SpaceCadetPinball/gdrv.cpp
@@ -1,6 +1,160 @@
#include "pch.h"
#include "gdrv.h"
+#include "memory.h"
+
+HPALETTE gdrv::palette_handle=0;
void gdrv::get_focus()
{
}
+
+
+gdrv_dib* gdrv::DibCreate(__int16 bpp, int width, int height)
+{
+ auto sizeBytes = height * ((width * bpp / 8 + 3) & 0xFFFFFFFC);
+ auto buf = GlobalAlloc(0x42u, sizeBytes + 1064);
+ auto dib = static_cast(GlobalLock(buf));
+
+ if (!dib)
+ return nullptr;
+ dib->BufferSize = sizeBytes;
+ dib->Width = width;
+ dib->PaletteOffset = 40;
+ dib->Height = height;
+ dib->Unknown3_1 = 1;
+ dib->Bpp = bpp;
+ dib->Unknown4 = 0;
+ dib->Unknown6 = 0;
+ dib->Unknown7 = 0;
+ dib->NumberOfColors = 0;
+ dib->Unknown9 = 0;
+ if (bpp == 4)
+ {
+ dib->NumberOfColors = 16;
+ }
+ else if (bpp == 8)
+ {
+ dib->NumberOfColors = 256;
+ }
+
+ auto pltPtr = &dib->Palette0;
+ for (auto index = 0; index < dib->NumberOfColors / 16; ++index, pltPtr++)
+ {
+ *pltPtr = gdrv_dib_palette{
+ {0},
+ {0x800000},
+ {0x8000},
+ {8421376},
+ {128},
+ {8388736},
+ {32896},
+ {12632256},
+ {8421504},
+ {16711680},
+ {65280},
+ {16776960},
+ {255},
+ {16711935},
+ {0xFFFF},
+ {0xFFFFFF},
+ };
+ }
+ return dib;
+}
+
+
+void gdrv::DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag)
+{
+ tagPALETTEENTRY pPalEntries[256]; // [esp+4h] [ebp-400h]
+
+ if (!hpal)
+ hpal = static_cast(GetStockObject(DEFAULT_PALETTE));
+ if (!dib)
+ return;
+ int numOfColors = dib->NumberOfColors;
+ if (!numOfColors)
+ {
+ auto bpp = dib->Bpp;
+ if (bpp <= 8u)
+ numOfColors = 1 << bpp;
+ }
+ if (numOfColors > 0 && (dib->Unknown4 != 3 || numOfColors == 3))
+ {
+ if (someFlag && someFlag <= 2)
+ {
+ auto pltPtr = (short*)((char*)dib + dib->PaletteOffset);
+ for (int i = 0; i < numOfColors; ++i)
+ {
+ *pltPtr++ = i;
+ }
+ }
+ else
+ {
+ assertm(false, "Entered bad code");
+ char* dibPtr = (char*)dib + dib->PaletteOffset;
+ if (numOfColors >= 256)
+ numOfColors = 256;
+ GetPaletteEntries(hpal, 0, numOfColors, pPalEntries);
+ int index = 0;
+ char* dibPtr2 = dibPtr + 1;
+ do
+ {
+ char v9 = pPalEntries[index++].peRed;
+ dibPtr2[1] = v9;
+ *dibPtr2 = dibPtr2[(char*)pPalEntries - dibPtr];
+ *(dibPtr2 - 1) = dibPtr2[&pPalEntries[0].peGreen - (unsigned char*)dibPtr];
+ dibPtr2[2] = 0;
+ dibPtr2 += 4;
+ }
+ while (index < numOfColors);
+ }
+ }
+}
+
+
+int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
+{
+ char* bmpBufPtr; // ecx
+ gdrv_dib* dib = DibCreate(8, width, height);
+ DibSetUsage(dib, palette_handle, 1);
+
+ bmp->Dib = dib;
+ bmp->Width = width;
+ bmp->Stride = width;
+ if (width % 4)
+ bmp->Stride = 4 - width % 4 + width;
+ gdrv_dib* dib2 = bmp->Dib;
+ bmp->Height = height;
+ bmp->SomeByte = 2;
+
+ if (dib2->Unknown4 == 3)
+ bmpBufPtr = (char*)&dib2->Unknown3_1 + dib2->PaletteOffset;
+ else
+ bmpBufPtr = (char*)&dib2->PaletteOffset + 4 * dib2->NumberOfColors + dib2->PaletteOffset;
+ bmp->BmpBufPtr1 = bmpBufPtr;
+ bmp->BmpBufPtr2 = bmpBufPtr;
+ return 0;
+}
+
+int gdrv::create_bitmap(gdrv_bitmap8* bmp, int width, int height)
+{
+ return create_bitmap_dib(bmp, width, height);
+}
+
+int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
+{
+ bmp->Dib = nullptr;
+ bmp->Width = width;
+ bmp->Stride = width;
+ if (flag && width % 4)
+ bmp->Stride = width - width % 4 + 4;
+ unsigned int sizeInBytes = height * bmp->Stride;
+ bmp->Height = height;
+ bmp->SomeByte = 1;
+ char* buf = memory::allocate(sizeInBytes);
+ bmp->BmpBufPtr1 = buf;
+ if (!buf)
+ return -1;
+ bmp->BmpBufPtr2 = buf;
+ return 0;
+}
diff --git a/SpaceCadetPinball/gdrv.h b/SpaceCadetPinball/gdrv.h
index 70a44dc..10312aa 100644
--- a/SpaceCadetPinball/gdrv.h
+++ b/SpaceCadetPinball/gdrv.h
@@ -1,7 +1,93 @@
#pragma once
+
+union tagPALETTEENTRY2
+{
+ unsigned __int32 PltInt;
+ tagPALETTEENTRY Plt;
+};
+
+struct gdrv_dib_palette
+{
+ tagPALETTEENTRY2 Color0;
+ tagPALETTEENTRY2 Color1;
+ tagPALETTEENTRY2 Color2;
+ tagPALETTEENTRY2 Color3;
+ tagPALETTEENTRY2 Color4;
+ tagPALETTEENTRY2 Color5;
+ tagPALETTEENTRY2 Color6;
+ tagPALETTEENTRY2 Color7;
+ tagPALETTEENTRY2 Color8;
+ tagPALETTEENTRY2 Color9;
+ tagPALETTEENTRY2 Color10;
+ tagPALETTEENTRY2 Color11;
+ tagPALETTEENTRY2 Color12;
+ tagPALETTEENTRY2 Color13;
+ tagPALETTEENTRY2 Color14;
+ tagPALETTEENTRY2 Color15;
+};
+
+struct __declspec(align(4)) gdrv_dib
+{
+ int PaletteOffset;
+ int Width;
+ int Height;
+ __int16 Unknown3_1;
+ unsigned __int16 Bpp;
+ int Unknown4;
+ int BufferSize;
+ int Unknown6;
+ int Unknown7;
+ int NumberOfColors;
+ int Unknown9;
+ gdrv_dib_palette Palette0;
+ gdrv_dib_palette Palette1;
+ gdrv_dib_palette Palette2;
+ gdrv_dib_palette Palette3;
+ gdrv_dib_palette Palette4;
+ gdrv_dib_palette Palette5;
+ gdrv_dib_palette Palette6;
+ gdrv_dib_palette Palette7;
+ gdrv_dib_palette Palette8;
+ gdrv_dib_palette Palette9;
+ gdrv_dib_palette Palette10;
+ gdrv_dib_palette Palette11;
+ gdrv_dib_palette Palette12;
+ gdrv_dib_palette Palette13;
+ gdrv_dib_palette Palette14;
+ gdrv_dib_palette Palette15;
+ char BmpBuffer[1];
+};
+
+#pragma pack(push, 1)
+struct __declspec(align(1)) gdrv_bitmap8
+{
+ gdrv_dib* Dib;
+ char* BmpBufPtr2;
+ char* BmpBufPtr1;
+ int Width;
+ int Height;
+ int Stride;
+ char SomeByte;
+ int Color6;
+ int XPosition;
+ int YPosition;
+};
+#pragma pack(pop)
+
+static_assert(sizeof(tagPALETTEENTRY2) == 4, "Wrong size of tagPALETTEENTRY2");
+static_assert(sizeof(gdrv_dib_palette) == 4 * 16, "Wrong size of gdrv_dib_palette");
+static_assert(sizeof(gdrv_dib) == (10 * 4) + sizeof(gdrv_dib_palette) * 16 + 4, "Wrong size of gdrv_dib");
+static_assert(sizeof(gdrv_bitmap8) == 37, "Wrong size of gdrv_bitmap8");
+
class gdrv
{
public:
- static void get_focus();
+ static HPALETTE palette_handle;
+ static void get_focus();
+ static gdrv_dib* DibCreate(__int16 bpp, int width, int height);
+ static void DibSetUsage(gdrv_dib* dib, HPALETTE hpal, int someFlag);
+ static int create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height);
+ static int create_bitmap(gdrv_bitmap8* bmp, int width, int height);
+ static int create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag);
+private:
};
-
diff --git a/SpaceCadetPinball/loader.cpp b/SpaceCadetPinball/loader.cpp
index 3ffb67e..fb7ba3b 100644
--- a/SpaceCadetPinball/loader.cpp
+++ b/SpaceCadetPinball/loader.cpp
@@ -1,10 +1,9 @@
#include "pch.h"
#include "loader.h"
-
-
#include "memory.h"
#include "partman.h"
#include "pinball.h"
+#include "zdrv.h"
/*_loader_errors dd 0, offset aBadHandle, 1, offset aNoTypeField, 2, offset aNoAttributesFi
@@ -91,8 +90,8 @@ void loader::default_vsi(visualStruct* visual)
visual->Unknown2F = 0.60000002f;
visual->FloatArrSizeDiv8Sub2 = 0;
visual->SoundIndex2 = 0;
- visual->Bitmap8 = 0;
- visual->Bitmap16 = 0;
+ visual->Bitmap = 0;
+ visual->ZMap = 0;
visual->SoundIndex3 = 0;
visual->SoundIndex4 = 0;
}
@@ -107,7 +106,7 @@ void loader::loadfrom(datFileStruct* datFile)
{
do
{
- __int16* value = (__int16*)partman::field(datFile, groupIndex, ShortValue);
+ __int16* value = (__int16*)partman::field(datFile, groupIndex, datFieldTypes::ShortValue);
if (value && *value == 202)
{
soundIndex = sound_count;
@@ -170,10 +169,10 @@ int loader::get_sound_id(int groupIndex)
sound_list[soundIndex].Volume = 0.0;
if (soundGroupId > 0 && !pinball::quickFlag)
{
- __int16* value = (__int16*)partman::field(loader_table, soundGroupId, ShortValue);
+ __int16* value = (__int16*)partman::field(loader_table, soundGroupId, datFieldTypes::ShortValue);
if (value && *value == 202)
{
- const CHAR* fileName = partman::field(loader_table, soundGroupId, String);
+ const CHAR* fileName = partman::field(loader_table, soundGroupId, datFieldTypes::String);
HFILE hFile = _lopen(fileName, 0);
sound_list[soundIndex].Volume = (float)((double)(_llseek(hFile, 0, 2)) * 0.0000909090909090909);
_lclose(hFile);
@@ -198,7 +197,7 @@ short loader::query_visual_states(int groupIndex)
short result;
if (groupIndex < 0)
return error(0, 17);
- __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, ShortArray);
+ __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, datFieldTypes::ShortArray);
if (shortArr && *shortArr == 100)
result = shortArr[1];
else
@@ -209,7 +208,7 @@ short loader::query_visual_states(int groupIndex)
char* loader::query_name(int groupIndex)
{
if (groupIndex >= 0)
- return partman::field(loader_table, groupIndex, GroupName);
+ return partman::field(loader_table, groupIndex, datFieldTypes::GroupName);
error(0, 19);
return nullptr;
}
@@ -222,12 +221,12 @@ __int16* loader::query_iattribute(int groupIndex, int firstValue, int* arraySize
{
while (true)
{
- __int16* shortArr = (__int16*)partman::field_nth(loader_table, groupIndex, ShortArray, skipIndex);
+ __int16* shortArr = (__int16*)partman::field_nth(loader_table, groupIndex, datFieldTypes::ShortArray, skipIndex);
if (!shortArr)
break;
if (*shortArr == firstValue)
{
- *arraySize = partman::field_size(loader_table, groupIndex, ShortArray) / 2 - 1;
+ *arraySize = partman::field_size(loader_table, groupIndex, datFieldTypes::ShortArray) / 2 - 1;
return shortArr + 1;
}
++skipIndex;
@@ -255,7 +254,7 @@ float* loader::query_float_attribute(int groupIndex, int groupIndexOffset, int f
{
while (true)
{
- float* floatArr = (float*)partman::field_nth(loader_table, groupIndexSum, FloatArray, skipIndex);
+ float* floatArr = (float*)partman::field_nth(loader_table, groupIndexSum, datFieldTypes::FloatArray, skipIndex);
if (!floatArr)
break;
if (static_cast<__int16>(static_cast<__int64>(floor(*floatArr))) == firstValue)
@@ -283,16 +282,16 @@ int loader::material(int groupIndex, visualStruct* visual)
{
if (groupIndex < 0)
return error(0, 21);
- __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, ShortValue);
+ __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, datFieldTypes::ShortValue);
if (!shortArr)
return error(1, 21);
if (*shortArr != 300)
return error(3, 21);
- float* floatArr = (float*)partman::field(loader_table, groupIndex, FloatArray);
+ float* floatArr = (float*)partman::field(loader_table, groupIndex, datFieldTypes::FloatArray);
if (!floatArr)
return error(11, 21);
int index = 0;
- int floatArrLength = partman::field_size(loader_table, groupIndex, FloatArray) >> 2;
+ int floatArrLength = partman::field_size(loader_table, groupIndex, datFieldTypes::FloatArray) >> 2;
if (floatArrLength > 0)
{
do
@@ -336,7 +335,7 @@ int loader::state_id(int groupIndex, int groupIndexOffset)
__int16 visualState = query_visual_states(groupIndex);
if (visualState <= 0)
return error(12, 24);
- __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, ShortValue);
+ __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, datFieldTypes::ShortValue);
if (!shortArr)
return error(1, 24);
if (*shortArr != 200)
@@ -347,7 +346,7 @@ int loader::state_id(int groupIndex, int groupIndexOffset)
return groupIndex2;
groupIndex2 = groupIndexOffset + groupIndex;
- shortArr = (__int16*)partman::field(loader_table, groupIndexOffset + groupIndex, ShortValue);
+ shortArr = (__int16*)partman::field(loader_table, groupIndexOffset + groupIndex, datFieldTypes::ShortValue);
if (!shortArr)
return error(1, 24);
if (*shortArr != 201)
@@ -361,15 +360,15 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker)
{
if (groupIndex < 0)
return error(0, 20);
- __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, ShortValue);
+ __int16* shortArr = (__int16*)partman::field(loader_table, groupIndex, datFieldTypes::ShortValue);
if (!shortArr)
return error(1, 20);
if (*shortArr != 400)
return error(4, 20);
- float* floatArr = (float*)partman::field(loader_table, groupIndex, FloatArray);
+ float* floatArr = (float*)partman::field(loader_table, groupIndex, datFieldTypes::FloatArray);
if (!floatArr)
return error(11, 20);
- int floatArrLength = partman::field_size(loader_table, groupIndex, FloatArray) >> 2;
+ int floatArrLength = partman::field_size(loader_table, groupIndex, datFieldTypes::FloatArray) >> 2;
int index = 0;
if (floatArrLength <= 0)
return 0;
@@ -418,7 +417,7 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
visualStruct* visual2; // edi
int groupIndexSum; // eax
int groupIndexSum2; // ebx
- char* bitmap16; // eax
+ zmap_header_type* bitmap16; // eax
__int16* shortArr; // esi
unsigned int shortArrSize; // eax
int index; // ebx
@@ -447,18 +446,18 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
groupIndexSum3 = groupIndexSum;
if (groupIndexSum < 0)
return error(16, 18);
- visual->Bitmap8 = partman::field(loader_table, groupIndexSum, Bitmap8bit);
- bitmap16 = partman::field(loader_table, groupIndexSum2, Bitmap16bit);
- visual->Bitmap16 = bitmap16;
+ visual->Bitmap = (gdrv_bitmap8*)partman::field(loader_table, groupIndexSum, datFieldTypes::Bitmap8bit);
+ bitmap16 = (zmap_header_type*)partman::field(loader_table, groupIndexSum2, datFieldTypes::Bitmap16bit);
+ visual->ZMap = bitmap16;
if (bitmap16)
{
- //*(int*)(bitmap16 + 6) = bitmap16 + 14;
- //*(int*)(visual->Bitmap16 + 10) = *(int*)(visual->Bitmap16 + 6);
+ bitmap16->BmpBufPtr1 = bitmap16->BmpBuffer;
+ visual->ZMap->bmpBufPtr2 = visual->ZMap->BmpBufPtr1;
}
- shortArr = (__int16*)partman::field(loader_table, groupIndexSum2, ShortArray);
+ shortArr = (__int16*)partman::field(loader_table, groupIndexSum2, datFieldTypes::ShortArray);
if (shortArr)
{
- shortArrSize = partman::field_size(loader_table, groupIndexSum2, ShortArray);
+ shortArrSize = partman::field_size(loader_table, groupIndexSum2, datFieldTypes::ShortArray);
index = 0;
shortArrLength = shortArrSize >> 1;
if ((__int16)(shortArrSize >> 1) > 0)
@@ -540,13 +539,13 @@ int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* vi
LABEL_33:
if (!visual2->Unknown14Flag)
visual2->Unknown14Flag = 1;
- floatArr = (float*)partman::field(loader_table, groupIndexSum3, FloatArray);
+ floatArr = (float*)partman::field(loader_table, groupIndexSum3, datFieldTypes::FloatArray);
if (!floatArr)
return 0;
nextFloatVal = floatArr + 1;
if (*floatArr != 600.0)
return 0;
- visual2->FloatArrSizeDiv8Sub2 = (partman::field_size(loader_table, groupIndexSum3, FloatArray) >> 2)/ 2- 2;
+ visual2->FloatArrSizeDiv8Sub2 = (partman::field_size(loader_table, groupIndexSum3, datFieldTypes::FloatArray) >> 2)/ 2- 2;
floatVal = (__int64)(floor(*nextFloatVal) - 1.0);
floatArrPtr = nextFloatVal + 1;
if ((int)floatVal)
diff --git a/SpaceCadetPinball/loader.h b/SpaceCadetPinball/loader.h
index 0b0f966..aaadbbe 100644
--- a/SpaceCadetPinball/loader.h
+++ b/SpaceCadetPinball/loader.h
@@ -1,4 +1,6 @@
#pragma once
+#include "gdrv.h"
+#include "zdrv.h"
struct datFileStruct;
@@ -42,8 +44,8 @@ struct __declspec(align(4)) visualStruct
int Unknown14Flag;
int SoundIndex4;
int SoundIndex3;
- char* Bitmap8;
- char* Bitmap16;
+ gdrv_bitmap8* Bitmap;
+ zmap_header_type* ZMap;
};
diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp
new file mode 100644
index 0000000..7171477
--- /dev/null
+++ b/SpaceCadetPinball/maths.cpp
@@ -0,0 +1,36 @@
+#include "pch.h"
+#include "maths.h"
+
+
+void maths::enclosing_box(visual_rect* rect1, visual_rect* rect2, visual_rect* dstRect)
+{
+ int xPos1 = rect1->XPosition;
+ int yPos1 = rect1->YPosition;
+ int width1 = rect1->Width;
+ int height1 = rect1->Height;
+ int xPos2 = rect2->XPosition;
+ bool rect2XPosLessRect1 = rect2->XPosition < rect1->XPosition;
+ int yPos2 = rect2->YPosition;
+ int width2 = rect2->Width;
+ int height2 = rect2->Height;
+ int xPos2_2 = rect2->XPosition;
+ if (rect2XPosLessRect1)
+ {
+ width1 += xPos1 - xPos2;
+ xPos1 = xPos2;
+ }
+ if (yPos2 < yPos1)
+ {
+ height1 += yPos1 - yPos2;
+ yPos1 = yPos2;
+ }
+ if (width2 + xPos2 > xPos1 + width1)
+ width1 = xPos2_2 + width2 - xPos1;
+ int height1_2 = height1;
+ if (height2 + yPos2 > height1 + yPos1)
+ height1_2 = yPos2 + height2 - yPos1;
+ dstRect->YPosition = yPos1;
+ dstRect->Height = height1_2;
+ dstRect->XPosition = xPos1;
+ dstRect->Width = width1;
+}
\ No newline at end of file
diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h
new file mode 100644
index 0000000..18e6c26
--- /dev/null
+++ b/SpaceCadetPinball/maths.h
@@ -0,0 +1,18 @@
+#pragma once
+
+
+struct __declspec(align(4)) visual_rect
+{
+ int XPosition;
+ int YPosition;
+ int Width;
+ int Height;
+};
+
+class maths
+{
+public:
+ static void enclosing_box(visual_rect* rect1, visual_rect* rect2, visual_rect* dstRect);
+
+};
+
diff --git a/SpaceCadetPinball/partman.cpp b/SpaceCadetPinball/partman.cpp
index 409852f..1d77b4c 100644
--- a/SpaceCadetPinball/partman.cpp
+++ b/SpaceCadetPinball/partman.cpp
@@ -1,6 +1,6 @@
#include "pch.h"
#include "partman.h"
-
+#include "gdrv.h"
#include "memory.h"
short partman::_field_size[] = {
@@ -39,7 +39,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
else
{
int lenOfStr = lstrlenA(Buffer.Description);
- auto descriptionBuf = (char*)memory::allocate(lenOfStr + 1);
+ auto descriptionBuf = static_cast(memory::allocate(lenOfStr + 1));
datFile->Description = descriptionBuf;
if (!descriptionBuf)
{
@@ -52,7 +52,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
if (Buffer.Unknown)
{
- auto unknownBuf = (char*)memory::allocate(Buffer.Unknown);
+ auto unknownBuf = static_cast(memory::allocate(Buffer.Unknown));
if (!unknownBuf)
{
_lclose(fileHandle);
@@ -99,30 +99,30 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
{
auto entryType = static_cast(_lread_char(fileHandle));
entryData->EntryType = entryType;
- int fieldSize = _field_size[entryType];
+ int fieldSize = _field_size[(int)entryType];
if (fieldSize < 0)
{
fieldSize = _lread_long(fileHandle);
}
- if (entryType == Bitmap8bit)
+ if (entryType == datFieldTypes::Bitmap8bit)
{
_hread(fileHandle, &bmpHeader, 14);
- char* bmpBuffer = (char*)memory::allocate(0x25u);
- entryData->Buffer = bmpBuffer;
- if (!bmpBuffer)
+ auto bmp = (gdrv_bitmap8*)memory::allocate(sizeof(gdrv_bitmap8));
+ entryData->Buffer = (char*)bmp;
+ if (!bmp)
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*)memory::allocate(bmpHeader.Size);
- _hread(fileHandle, tempBuff, bmpHeader.Size);
- memory::free(tempBuff);
- //*((int*)entryData->Buffer + 29) = bmpHeader.XPosition;
- //*((int*)entryData->Buffer + 33) = bmpHeader.YPosition;
+ if (bmpHeader.Unknown2 & 2
+ ? gdrv::create_bitmap(bmp, bmpHeader.Width, bmpHeader.Height)
+ : gdrv::create_raw_bitmap(bmp, bmpHeader.Width, bmpHeader.Height,
+ bmpHeader.Unknown2 & 1))
+ goto LABEL_41;
+ _hread(fileHandle, bmp->BmpBufPtr1, bmpHeader.Size);
+ bmp->XPosition = bmpHeader.XPosition;
+ bmp->YPosition = bmpHeader.YPosition;
}
else
- {
- char* entryBuffer = (char*)memory::allocate(fieldSize);
+ {
+ char* entryBuffer = static_cast(memory::allocate(fieldSize));
entryData->Buffer = entryBuffer;
if (!entryBuffer)
goto LABEL_41;
@@ -193,7 +193,7 @@ char* partman::field(datFileStruct* datFile, int groupIndex, datFieldTypes targe
datEntryData* entry = groupData->Entries;
while (true)
{
- int entryType = entry->EntryType;
+ auto entryType = entry->EntryType;
if (entryType == targetEntryType)
break;
if (entryType > targetEntryType)
@@ -217,7 +217,7 @@ char* partman::field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes t
datEntryData* entry = groupData->Entries;
do
{
- int entryType = entry->EntryType;
+ auto entryType = entry->EntryType;
if (entryType == targetEntryType)
{
if (skipCount == skipFirstN)
@@ -250,7 +250,7 @@ int partman::field_size_nth(datFileStruct* datFile, int groupIndex, datFieldType
datEntryData* entry = groupData->Entries;
do
{
- int entryType = entry->EntryType;
+ auto entryType = entry->EntryType;
if (entryType == targetEntryType)
{
if (skipCount == skipFirstN)
@@ -287,7 +287,7 @@ int partman::record_labeled(datFileStruct* datFile, LPCSTR targetGroupName)
{
if (--groupIndex < 0)
return -1;
- char* groupName = field(datFile, groupIndex, GroupName);
+ char* groupName = field(datFile, groupIndex, datFieldTypes::GroupName);
if (groupName)
{
int index = 0;
diff --git a/SpaceCadetPinball/partman.h b/SpaceCadetPinball/partman.h
index 2b1decf..f54c573 100644
--- a/SpaceCadetPinball/partman.h
+++ b/SpaceCadetPinball/partman.h
@@ -1,6 +1,6 @@
#pragma once
-enum datFieldTypes : __int16
+enum class datFieldTypes : __int16
{
ShortValue = 0,
//, does not have the 32bits size value, but a 16bits value(see above).
diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp
index 71beaa0..68548d2 100644
--- a/SpaceCadetPinball/render.cpp
+++ b/SpaceCadetPinball/render.cpp
@@ -1,7 +1,15 @@
#include "pch.h"
#include "render.h"
+#include "memory.h"
+
int render::blit = 0;
+int render::many_dirty, render::many_sprites, render::many_balls;
+render_sprite_type_struct **render::dirty_list = new render_sprite_type_struct*[1000], **render::sprite_list = new
+ render_sprite_type_struct* [1000], **render::ball_list = new render_sprite_type_struct* [
+ 1000];
+zmap_header_type* render::background_zmap;
+int render::zmap_offset, render::zmap_offsetY;
void render::update()
{
@@ -13,4 +21,78 @@ void render::paint()
/*render_paint_balls();
gdrv_blat((int)&vscreen, xDest, yDest);
render_unpaint_balls();*/
-}
\ No newline at end of file
+}
+
+
+int render::sprite_modified(render_sprite_type_struct* sprite)
+{
+ int result = 0; // eax
+
+ if (sprite->VisualType == VisualType::Ball)
+ return result;
+ result = many_dirty;
+ if (many_dirty < 999)
+ dirty_list[many_dirty++] = sprite;
+ return result;
+}
+
+render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bitmap8* rootBmp8, zmap_header_type* zMap,
+ int xPosition, int yPosition, visual_rect* rect)
+{
+ render_sprite_type_struct* sprite = (render_sprite_type_struct*)memory::allocate(0x5Cu);
+ render_sprite_type_struct* result = nullptr;
+ if (!sprite)
+ return result;
+ sprite->YPosition = yPosition;
+ sprite->RootBmp8 = rootBmp8;
+ sprite->XPosition = xPosition;
+ sprite->VisualType = visualType;
+ sprite->Unknown6_0 = 0;
+ sprite->Unknown17 = 0;
+ sprite->Unknown18 = 0;
+ if (rect)
+ {
+ sprite->Rect = *rect;
+ }
+ else
+ {
+ sprite->Rect.Width = -1;
+ sprite->Rect.Height = -1;
+ sprite->Rect.XPosition = 0;
+ sprite->Rect.YPosition = 0;
+ }
+ if (rootBmp8)
+ {
+ sprite->Bmp8Width = rootBmp8->Width;
+ sprite->Bmp8Height = rootBmp8->Height;
+ }
+ else
+ {
+ sprite->Bmp8Width = 0;
+ sprite->Bmp8Height = 0;
+ }
+ sprite->ZMap = zMap;
+ sprite->ZMapOffestX = 0;
+ sprite->ZMapOffestY = 0;
+ if (!zMap && visualType != VisualType::Ball)
+ {
+ sprite->ZMap = background_zmap;
+ sprite->ZMapOffestY = xPosition - zmap_offset;
+ sprite->ZMapOffestX = yPosition - zmap_offsetY;
+ }
+ sprite->XPosition2 = sprite->XPosition;
+ sprite->YPosition2 = sprite->YPosition;
+ sprite->Bmp8Width2 = sprite->Bmp8Width;
+ sprite->Bmp8Height2 = sprite->Bmp8Height;
+ if (visualType == VisualType::Ball)
+ {
+ ball_list[many_balls++] = sprite;
+ }
+ else
+ {
+ sprite_list[many_sprites++] = sprite;
+ sprite_modified(sprite);
+ }
+ result = sprite;
+ return result;
+}
diff --git a/SpaceCadetPinball/render.h b/SpaceCadetPinball/render.h
index 8555168..78c85ed 100644
--- a/SpaceCadetPinball/render.h
+++ b/SpaceCadetPinball/render.h
@@ -1,9 +1,55 @@
#pragma once
+#include "gdrv.h"
+#include "maths.h"
+#include "zdrv.h"
+
+enum class VisualType : char
+{
+ None = 0,
+ Sprite = 1,
+ Ball = 2
+};
+
+struct __declspec(align(4)) render_sprite_type_struct
+{
+ int XPosition;
+ int YPosition;
+ int Bmp8Width;
+ int Bmp8Height;
+ gdrv_bitmap8* RootBmp8;
+ zmap_header_type* ZMap;
+ char Unknown6_0;
+ VisualType VisualType;
+ char Unknown6_2;
+ char Unknown6_3;
+ int XPosition2;
+ int YPosition2;
+ int Bmp8Width2;
+ int Bmp8Height2;
+ int ZMapOffestY;
+ int ZMapOffestX;
+ int Unknown13;
+ int Unknown14;
+ int Unknown15;
+ int Unknown16;
+ int Unknown17;
+ int Unknown18;
+ visual_rect Rect;
+};
+
class render
{
public:
static int blit;
+ static int many_dirty, many_sprites, many_balls;
+ static render_sprite_type_struct **dirty_list, **sprite_list, **ball_list;
+ static zmap_header_type* background_zmap;
+ static int zmap_offset, zmap_offsetY;
+
static void update();
static void paint();
+ static int sprite_modified(render_sprite_type_struct* sprite);
+ static render_sprite_type_struct* create_sprite(VisualType visualType, gdrv_bitmap8* rootBmp8,
+ zmap_header_type* zMap,
+ int xPosition, int yPosition, visual_rect* rect);
};
-
diff --git a/SpaceCadetPinball/score.cpp b/SpaceCadetPinball/score.cpp
index 5fbbbe3..101ad74 100644
--- a/SpaceCadetPinball/score.cpp
+++ b/SpaceCadetPinball/score.cpp
@@ -17,7 +17,7 @@ scoreStruct* score::create(LPCSTR fieldName, int renderBgBmp)
return nullptr;
score->Unknown1 = -9999;
score->RenderBgBmp = renderBgBmp;
- __int16* shortArr = (__int16*)partman::field_labeled(loader::loader_table, fieldName, ShortArray);
+ __int16* shortArr = (__int16*)partman::field_labeled(loader::loader_table, fieldName, datFieldTypes::ShortArray);
if (!shortArr)
{
memory::free(score);
@@ -32,7 +32,7 @@ scoreStruct* score::create(LPCSTR fieldName, int renderBgBmp)
int index = 10;
do
{
- *bmpPtr = partman::field(loader::loader_table, groupIndex, Bitmap8bit);
+ *bmpPtr = partman::field(loader::loader_table, groupIndex, datFieldTypes::Bitmap8bit);
++bmpPtr;
++groupIndex;
--index;
diff --git a/SpaceCadetPinball/zdrv.cpp b/SpaceCadetPinball/zdrv.cpp
new file mode 100644
index 0000000..01f2c4d
--- /dev/null
+++ b/SpaceCadetPinball/zdrv.cpp
@@ -0,0 +1,2 @@
+#include "pch.h"
+#include "zdrv.h"
diff --git a/SpaceCadetPinball/zdrv.h b/SpaceCadetPinball/zdrv.h
new file mode 100644
index 0000000..cd26bdf
--- /dev/null
+++ b/SpaceCadetPinball/zdrv.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#pragma pack(push, 1)
+struct __declspec(align(1)) zmap_header_type
+{
+ __int16 Width;
+ __int16 Height;
+ __int16 Stride;
+ char* BmpBufPtr1;
+ char* bmpBufPtr2;
+ char BmpBuffer[1];
+};
+#pragma pack(pop)
+
+static_assert(sizeof(zmap_header_type) == 15, "Wrong size of zmap_header_type");
+
+class zdrv
+{
+public:
+
+};
+