Added loader for Full Tilt .dat files, v1.

Works with some data hacks in lowest resolution.
Seems to work ok, even though BL is still 3DPB.
This commit is contained in:
Muzychenko Andrey 2021-01-31 17:29:53 +03:00
parent 6ff457eb68
commit 49f6132d23
18 changed files with 205 additions and 48 deletions

View file

@ -39,21 +39,21 @@ Type Meaning/comments
9 String (content) 9 String (content)
10 Array of 16bits integer values 10 Array of 16bits integer values
11 Array of 32bits floating point values (collision box, ...) 11 Array of 32bits floating point values (collision box, ...)
12 16 bpp bitmap (Heightmap?) 12 16 bpp bitmap (zMap)
//-- 8bpp bitmap data header --// //-- 8bpp bitmap data header --//
+0: Unknown (0) BYTE +0: Resolution BYTE 0=640x480, 1=800x600, 2=1024x768, -1=Load in all resolutions
+1: Width WORD +1: Width WORD
+3: Height WORD +3: Height WORD
+5: X position WORD +5: X position WORD
+7 Y position WORD +7 Y position WORD
+9: Size of bitmap DWORD +9: Size of bitmap DWORD
+13: Unknown (1) BYTE +13: Flags BYTE bit0=Raw bmp align; bit1=DibBitmap, raw when 0; bit2=Spliced bitmap (aka skipline), combines bmp and zMap in RLE-like way
+14: Bitmap data BYTE*(DWORD@+9) +14: Bitmap data BYTE*(DWORD@+9)
//-- 16bpp bitmap data header --// //-- 16bpp zMap data header --//
+0: Width WORD +0: Width WORD
+2: Height WORD +2: Height WORD
+4: Pitch/2 WORD +4: Pitch/2 WORD
@ -62,6 +62,16 @@ Type Meaning/comments
+12: Unknown (80) WORD +12: Unknown (80) WORD
+14: Bitmap data BYTE*(DWORD@+9) +14: Bitmap data BYTE*(DWORD@+9)
//-- 16bpp zMap data header full tilt --//
+0: Resolution BYTE 0=640x480, 1=800x600, 2=1024x768, -1=Load in all resolutions
+1: Width WORD
+3: Height WORD
+5: Pitch/2 WORD
+7: Unknown (0) DWORD
+11: Unknown (0) WORD
+13: Unknown (80) WORD
+15: Bitmap data BYTE*(DWORD@+9)
//-- Pinball 3D remarkable groups --// //-- Pinball 3D remarkable groups --//

View file

@ -31,6 +31,10 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
ListBitmap = new objlist_class<gdrv_bitmap8>(0, 4); ListBitmap = new objlist_class<gdrv_bitmap8>(0, 4);
auto groupIndex = loader::query_handle("ball"); auto groupIndex = loader::query_handle("ball");
/*Full tilt hack - ball is ball0*/
if (groupIndex < 0)
groupIndex = loader::query_handle("ball0");
Offset = *loader::query_float_attribute(groupIndex, 0, 500); Offset = *loader::query_float_attribute(groupIndex, 0, 500);
auto visualCount = loader::query_visual_states(groupIndex); auto visualCount = loader::query_visual_states(groupIndex);
auto index = 0; auto index = 0;

View file

@ -27,6 +27,12 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
auto collMult = *floatArr; auto collMult = *floatArr;
auto bmpCoef2 = *floatArr2; auto bmpCoef2 = *floatArr2;
auto bmpCoef1 = *floatArr3; auto bmpCoef1 = *floatArr3;
/*Full tilt hack: different flipper speed*/
if (bmpCoef2 > 1)
bmpCoef2 = 0.08f;
if (bmpCoef1 > 1)
bmpCoef1 = 0.04f;
auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802)); auto vecT2 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 802));
auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801)); auto vecT1 = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 801));
auto origin = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 800)); auto origin = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, 0, 800));

View file

@ -19,16 +19,8 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
MessageField = 0; MessageField = 0;
Timer = 0; Timer = 0;
BallCapturedFlag = 0; BallCapturedFlag = 0;
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 407); Unknown3 = loader::query_float_attribute(groupIndex, 0, 407, 0.25f);
if (floatArr1) GravityMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
Unknown3 = *floatArr1;
else
Unknown3 = 0.25;
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 701);
if (floatArr2)
GravityMult = *floatArr2;
else
GravityMult = 0.5;
GravityPull = *loader::query_float_attribute(groupIndex, 0, 305); GravityPull = *loader::query_float_attribute(groupIndex, 0, 305);
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
@ -38,7 +30,8 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
if (Circle.RadiusSq == 0.0) if (Circle.RadiusSq == 0.0)
Circle.RadiusSq = 0.001f; Circle.RadiusSq = 0.001f;
auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup, reinterpret_cast<vector_type*>(visual.FloatArr), auto tCircle = new TCircle(this, &ActiveFlag, visual.CollisionGroup,
reinterpret_cast<vector_type*>(visual.FloatArr),
Circle.RadiusSq); Circle.RadiusSq);
if (tCircle) if (tCircle)
{ {
@ -49,6 +42,10 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2]; ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304))); FieldFlag = static_cast<int>(floor(*loader::query_float_attribute(groupIndex, 0, 1304)));
/*Full tilt hack - FieldFlag should be on*/
if (!FieldFlag)
FieldFlag = 1;
Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2]; Circle.RadiusSq = visual.FloatArr[2] * visual.FloatArr[2];
circle.RadiusSq = Circle.RadiusSq; circle.RadiusSq = Circle.RadiusSq;
circle.Center.X = Circle.Center.X; circle.Center.X = Circle.Center.X;

View file

@ -48,6 +48,19 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
zMap = ListZMap->Get(0); zMap = ListZMap->Get(0);
if (ListBitmap) if (ListBitmap)
{ {
/* Full tilt hack - spliced bitmap includes zMap
* Users access bitmap-zMap in pairs, pad zMap list with 0 for such users
* zdrv does not access zMap when drawing spliced bitmap*/
if (!ListZMap)
{
ListZMap = new objlist_class<zmap_header_type>(0, 4);
for (int index = 0; index < ListBitmap->GetCount(); index++)
{
assertm(ListBitmap->Get(index)->BitmapType == BitmapType::Spliced, "Wrong zMap padding");
ListZMap->Add(visual.ZMap);
}
}
rectangle_type bmp1Rect{}, tmpRect{}; rectangle_type bmp1Rect{}, tmpRect{};
auto rootBmp = ListBitmap->Get(0); auto rootBmp = ListBitmap->Get(0);
bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset; bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;

View file

@ -22,16 +22,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
loader::query_visual(groupIndex, 0, &visual); loader::query_visual(groupIndex, 0, &visual);
CollisionGroup = visual.CollisionGroup; CollisionGroup = visual.CollisionGroup;
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 701); BallFieldMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
if (floatArr1) RampFlag1 = static_cast<int>(loader::query_float_attribute(groupIndex, 0, 1305, 0));
BallFieldMult = *floatArr1;
else
BallFieldMult = 0.2f;
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 1305);
if (floatArr2)
RampFlag1 = static_cast<int>(floor(*floatArr2));
else
RampFlag1 = 0;
auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300); auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300);
RampPlaneCount = static_cast<int>(floor(*floatArr3Plane)); RampPlaneCount = static_cast<int>(floor(*floatArr3Plane));

View file

@ -49,11 +49,12 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
PinballTable->GravityAnglY = 1.570796f; PinballTable->GravityAnglY = 1.570796f;
} }
auto table3 = PinballTable; GraityDirX = cos(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
GraityDirX = cos(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult; GraityDirY = sin(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
GraityDiY = sin(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701); auto angleMultArr = loader::query_float_attribute(groupIndex, 0, 701);
if (angleMultArr)
/*Full tilt hack - GraityMult should be 0.2*/
if (angleMultArr && *angleMultArr < 1)
GraityMult = *angleMultArr; GraityMult = *angleMultArr;
else else
GraityMult = 0.2f; GraityMult = 0.2f;
@ -109,7 +110,7 @@ int TTableLayer::FieldEffect(TBall* ball, vector_type* vecDst)
{ {
vecDst->X = GraityDirX - (0.5f - static_cast<float>(rand()) * 0.00003051850947599719f + ball->Acceleration.X) * vecDst->X = GraityDirX - (0.5f - static_cast<float>(rand()) * 0.00003051850947599719f + ball->Acceleration.X) *
ball->Speed * GraityMult; ball->Speed * GraityMult;
vecDst->Y = GraityDiY - ball->Acceleration.Y * ball->Speed * GraityMult; vecDst->Y = GraityDirY - ball->Acceleration.Y * ball->Speed * GraityMult;
return 1; return 1;
} }

View file

@ -26,7 +26,7 @@ public:
float Unknown3F; float Unknown3F;
float Unknown4F; float Unknown4F;
float GraityDirX; float GraityDirX;
float GraityDiY; float GraityDirY;
int Unknown7; int Unknown7;
float GraityMult; float GraityMult;
field_effect_type Field; field_effect_type Field;

View file

@ -185,6 +185,21 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
return 0; return 0;
} }
int gdrv::create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size)
{
bmp->Dib = nullptr;
bmp->Width = width;
bmp->Stride = width;
bmp->BitmapType = BitmapType::Spliced;
bmp->Height = height;
char* buf = memory::allocate(size);
bmp->BmpBufPtr1 = buf;
if (!buf)
return -1;
bmp->BmpBufPtr2 = bmp->BmpBufPtr1;
return 0;
}
int gdrv::display_palette(PALETTEENTRY* plt) int gdrv::display_palette(PALETTEENTRY* plt)
{ {

View file

@ -5,6 +5,7 @@ enum class BitmapType : char
None = 0, None = 0,
RawBitmap = 1, RawBitmap = 1,
DibBitmap = 2, DibBitmap = 2,
Spliced = 4,
}; };
struct gdrv_bitmap8 struct gdrv_bitmap8
@ -50,6 +51,7 @@ public:
static int create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height); 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_bitmap(gdrv_bitmap8* bmp, int width, int height);
static int create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag); static int create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag);
static int create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size);
static int destroy_bitmap(gdrv_bitmap8* bmp); static int destroy_bitmap(gdrv_bitmap8* bmp);
static int display_palette(PALETTEENTRY* plt); static int display_palette(PALETTEENTRY* plt);
static UINT start_blit_sequence(); static UINT start_blit_sequence();

View file

@ -242,6 +242,37 @@ float* loader::query_float_attribute(int groupIndex, int groupIndexOffset, int f
return nullptr; return nullptr;
} }
float loader::query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue, float defVal)
{
if (groupIndex < 0)
{
error(0, 22);
return NAN;
}
int stateId = state_id(groupIndex, groupIndexOffset);
if (stateId < 0)
{
error(16, 22);
return NAN;
}
for (auto skipIndex = 0;; ++skipIndex)
{
auto floatArr = reinterpret_cast<float*>(partman::field_nth(loader_table, stateId,
datFieldTypes::FloatArray,skipIndex));
if (!floatArr)
break;
if (static_cast<__int16>(floor(*floatArr)) == firstValue)
return floatArr[1];
}
if (!isnan(defVal))
return defVal;
error(13, 22);
return NAN;
}
int loader::material(int groupIndex, visualStruct* visual) int loader::material(int groupIndex, visualStruct* visual)
{ {
if (groupIndex < 0) if (groupIndex < 0)

View file

@ -65,6 +65,7 @@ public:
static int query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual); static int query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual);
static char* query_name(int groupIndex); static char* query_name(int groupIndex);
static float* query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue); static float* query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue);
static float query_float_attribute(int groupIndex, int groupIndexOffset, int firstValue, float defVal);
static __int16* query_iattribute(int groupIndex, int firstValue, int* arraySize); static __int16* query_iattribute(int groupIndex, int firstValue, int* arraySize);
static float play_sound(int soundIndex); static float play_sound(int soundIndex);
static datFileStruct* loader_table; static datFileStruct* loader_table;

View file

@ -9,8 +9,7 @@ short partman::_field_size[] =
2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0 2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
}; };
datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode)
datFileStruct* partman::load_records(LPCSTR lpFileName)
{ {
_OFSTRUCT ReOpenBuff{}; _OFSTRUCT ReOpenBuff{};
datFileHeader header{}; datFileHeader header{};
@ -86,10 +85,10 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
if (!groupData) if (!groupData)
break; break;
groupData->EntryCount = entryCount; groupData->EntryCount = 0;
datEntryData* entryData = groupData->Entries;
for (auto entryIndex = 0; entryIndex < entryCount; ++entryIndex) for (auto entryIndex = 0; entryIndex < entryCount; ++entryIndex)
{ {
auto entryData = &groupData->Entries[groupData->EntryCount];
auto entryType = static_cast<datFieldTypes>(_lread_char(fileHandle)); auto entryType = static_cast<datFieldTypes>(_lread_char(fileHandle));
entryData->EntryType = entryType; entryData->EntryType = entryType;
@ -100,6 +99,12 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
if (entryType == datFieldTypes::Bitmap8bit) if (entryType == datFieldTypes::Bitmap8bit)
{ {
_hread(fileHandle, &bmpHeader, sizeof(dat8BitBmpHeader)); _hread(fileHandle, &bmpHeader, sizeof(dat8BitBmpHeader));
if (bmpHeader.Resolution != resolution && bmpHeader.Resolution != -1)
{
_llseek(fileHandle, bmpHeader.Size, 1);
continue;
}
auto bmp = reinterpret_cast<gdrv_bitmap8*>(memory::allocate(sizeof(gdrv_bitmap8))); auto bmp = reinterpret_cast<gdrv_bitmap8*>(memory::allocate(sizeof(gdrv_bitmap8)));
entryData->Buffer = reinterpret_cast<char*>(bmp); entryData->Buffer = reinterpret_cast<char*>(bmp);
if (!bmp) if (!bmp)
@ -107,10 +112,15 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
abort = true; abort = true;
break; break;
} }
if (bmpHeader.IsFlagSet(bmp8Flags::DibBitmap) int bmpRez;
? gdrv::create_bitmap(bmp, bmpHeader.Width, bmpHeader.Height) if (bmpHeader.IsFlagSet(bmp8Flags::Spliced))
: gdrv::create_raw_bitmap(bmp, bmpHeader.Width, bmpHeader.Height, bmpRez = gdrv::create_spliced_bitmap(bmp, bmpHeader.Width, bmpHeader.Height, bmpHeader.Size);
bmpHeader.IsFlagSet(bmp8Flags::RawBmpUnaligned))) else if (bmpHeader.IsFlagSet(bmp8Flags::DibBitmap))
bmpRez = gdrv::create_bitmap(bmp, bmpHeader.Width, bmpHeader.Height);
else
bmpRez = gdrv::create_raw_bitmap(bmp, bmpHeader.Width, bmpHeader.Height,
bmpHeader.IsFlagSet(bmp8Flags::RawBmpUnaligned));
if (bmpRez)
{ {
abort = true; abort = true;
break; break;
@ -121,6 +131,18 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
} }
else if (entryType == datFieldTypes::Bitmap16bit) else if (entryType == datFieldTypes::Bitmap16bit)
{ {
/*Full tilt has extra byte(@0:resolution) in zMap*/
if (fullTiltMode)
{
char zMapResolution = _lread_char(fileHandle);
fieldSize--;
if (zMapResolution != resolution && zMapResolution != -1)
{
_llseek(fileHandle, fieldSize, 1);
continue;
}
}
_hread(fileHandle, &zMapHeader, sizeof(dat16BitBmpHeader)); _hread(fileHandle, &zMapHeader, sizeof(dat16BitBmpHeader));
int length = fieldSize - sizeof(dat16BitBmpHeader); int length = fieldSize - sizeof(dat16BitBmpHeader);
@ -144,9 +166,9 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
} }
entryData->FieldSize = fieldSize; entryData->FieldSize = fieldSize;
datFile->NumberOfGroups = groupIndex + 1; groupData->EntryCount++;
++entryData;
} }
datFile->NumberOfGroups = groupIndex + 1;
} }
_lclose(fileHandle); _lclose(fileHandle);

View file

@ -29,6 +29,7 @@ enum class bmp8Flags : unsigned char
{ {
RawBmpUnaligned = 1 << 0, RawBmpUnaligned = 1 << 0,
DibBitmap = 1 << 1, DibBitmap = 1 << 1,
Spliced = 1 << 2,
}; };
@ -71,7 +72,7 @@ struct datFileStruct
#pragma pack(1) #pragma pack(1)
struct dat8BitBmpHeader struct dat8BitBmpHeader
{ {
char Unknown1; char Resolution;
__int16 Width; __int16 Width;
__int16 Height; __int16 Height;
__int16 XPosition; __int16 XPosition;
@ -108,7 +109,7 @@ static_assert(sizeof(dat16BitBmpHeader) == 14, "Wrong size of zmap_header_type")
class partman class partman
{ {
public: public:
static datFileStruct* load_records(LPCSTR lpFileName); static datFileStruct* load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode);
static void unload_records(datFileStruct* datFile); static void unload_records(datFileStruct* datFile);
static char* field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN); static char* field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN);
static char* field(datFileStruct* datFile, int groupIndex, datFieldTypes entryType); static char* field(datFileStruct* datFile, int groupIndex, datFieldTypes entryType);

View file

@ -37,8 +37,9 @@ int pb::init()
++memory::critical_allocation; ++memory::critical_allocation;
lstrcpyA(datFileName, winmain::DatFileName); lstrcpyA(datFileName, winmain::DatFileName);
//lstrcpyA(datFileName, "cadet.dat");
pinball::make_path_name(dataFilePath, datFileName, 300); pinball::make_path_name(dataFilePath, datFileName, 300);
record_table = partman::load_records(dataFilePath); record_table = partman::load_records(dataFilePath, 0, strstr(datFileName, "cadet"));
auto useBmpFont = 0; auto useBmpFont = 0;
pinball::get_rc_int(158, &useBmpFont); pinball::get_rc_int(158, &useBmpFont);
@ -55,6 +56,10 @@ int pb::init()
auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit); auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit);
auto cameraInfo = (float*)partman::field_labeled(record_table, "camera_info", datFieldTypes::FloatArray); auto cameraInfo = (float*)partman::field_labeled(record_table, "camera_info", datFieldTypes::FloatArray);
/*Full tilt hack - table size is hardcoded*/
if (!tableSize)
tableSize = new short[2]{600, 800};
if (cameraInfo) if (cameraInfo)
{ {
memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3); memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3);

View file

@ -25,4 +25,13 @@
/*Sound uses PlaySound*/ /*Sound uses PlaySound*/
#undef PlaySound #undef PlaySound
inline size_t pgm_save(int width, int height, char* data, FILE* outfile)
{
size_t n = 0;
n += fprintf(outfile, "P5\n%d %d\n%d\n", width, height, 0xFF);
n += fwrite(data, 1, width * height, outfile);
return n;
}
#endif //PCH_H #endif //PCH_H

View file

@ -1,6 +1,7 @@
#include "pch.h" #include "pch.h"
#include "zdrv.h" #include "zdrv.h"
#include "memory.h" #include "memory.h"
#include "pb.h"
int zdrv::create_zmap(zmap_header_type* zmap, int width, int height) int zdrv::create_zmap(zmap_header_type* zmap, int width, int height)
@ -59,6 +60,13 @@ void zdrv::paint(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, in
int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff, int srcBmpYOff, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, int srcBmpXOff, int srcBmpYOff,
zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff) zmap_header_type* srcZMap, int srcZMapXOff, int srcZMapYOff)
{ {
if (srcBmp->BitmapType == BitmapType::Spliced)
{
/*Spliced bitmap is also a zMap, how convenient*/
paint_spliced_bmp(srcBmp->XPosition, srcBmp->YPosition, dstBmp, dstZMap, srcBmp);
return;
}
int dstHeightAbs = abs(dstBmp->Height); int dstHeightAbs = abs(dstBmp->Height);
int srcHeightAbs = abs(srcBmp->Height); int srcHeightAbs = abs(srcBmp->Height);
auto srcPtr = &srcBmp->BmpBufPtr1[srcBmp->Stride * (srcHeightAbs - height - srcBmpYOff) + srcBmpXOff]; auto srcPtr = &srcBmp->BmpBufPtr1[srcBmp->Stride * (srcHeightAbs - height - srcBmpYOff) + srcBmpXOff];
@ -116,3 +124,41 @@ void zdrv::paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOf
zPtr += zMap->Stride - width; zPtr += zMap->Stride - width;
} }
} }
void zdrv::paint_spliced_bmp(int xPos, int yPos, gdrv_bitmap8* dstBmp, zmap_header_type* dstZmap, gdrv_bitmap8* srcBmp)
{
assertm(srcBmp->BitmapType == BitmapType::Spliced, "Wrong bmp type");
int xOffset = xPos - pb::MainTable->XOffset;
int yOffset = dstBmp->Height - srcBmp->Height - (yPos - pb::MainTable->YOffset);
if (yOffset < 0)
return;
auto bmpDstPtr = &dstBmp->BmpBufPtr2[xOffset + yOffset * dstBmp->Stride];
auto zMapDstPtr = &dstZmap->ZPtr2[xOffset + yOffset * dstZmap->Stride];
auto bmpSrcPtr = reinterpret_cast<unsigned short*>(srcBmp->BmpBufPtr2);
while (true)
{
auto stride = static_cast<short>(*bmpSrcPtr++);
if (stride < 0)
break;
/*Stride is in terms of dst stride, hardcoded to match vScreen width in current resolution*/
zMapDstPtr += stride;
bmpDstPtr += stride;
for (auto count = *bmpSrcPtr++; count; count--)
{
auto depth = *bmpSrcPtr++;
auto charPtr = reinterpret_cast<char**>(&bmpSrcPtr);
if (*zMapDstPtr >= depth)
{
*bmpDstPtr = **charPtr;
*zMapDstPtr = depth;
}
(*charPtr)++;
++zMapDstPtr;
++bmpDstPtr;
}
}
}

View file

@ -24,4 +24,6 @@ public:
static void paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff, static void paint_flat(int width, int height, gdrv_bitmap8* dstBmp, int dstBmpXOff, int dstBmpYOff,
zmap_header_type* zMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp, zmap_header_type* zMap, int dstZMapXOff, int dstZMapYOff, gdrv_bitmap8* srcBmp,
int srcBmpXOff, int srcBmpYOff, unsigned __int16 depth); int srcBmpXOff, int srcBmpYOff, unsigned __int16 depth);
static void paint_spliced_bmp(int xPos, int yPos, gdrv_bitmap8* dstBmp, zmap_header_type* dstZmap,
gdrv_bitmap8* srcBmp);
}; };