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: + +}; +