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.pull/5/head
parent
6ff457eb68
commit
49f6132d23
|
@ -39,21 +39,21 @@ Type Meaning/comments
|
|||
9 String (content)
|
||||
10 Array of 16bits integer values
|
||||
11 Array of 32bits floating point values (collision box, ...)
|
||||
12 16 bpp bitmap (Heightmap?)
|
||||
12 16 bpp bitmap (zMap)
|
||||
|
||||
|
||||
//-- 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
|
||||
+3: Height WORD
|
||||
+5: X position WORD
|
||||
+7 Y position WORD
|
||||
+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)
|
||||
|
||||
|
||||
//-- 16bpp bitmap data header --//
|
||||
//-- 16bpp zMap data header --//
|
||||
+0: Width WORD
|
||||
+2: Height WORD
|
||||
+4: Pitch/2 WORD
|
||||
|
@ -62,6 +62,16 @@ Type Meaning/comments
|
|||
+12: Unknown (80) WORD
|
||||
+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 --//
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
|||
|
||||
ListBitmap = new objlist_class<gdrv_bitmap8>(0, 4);
|
||||
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);
|
||||
auto visualCount = loader::query_visual_states(groupIndex);
|
||||
auto index = 0;
|
||||
|
|
|
@ -27,6 +27,12 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||
auto collMult = *floatArr;
|
||||
auto bmpCoef2 = *floatArr2;
|
||||
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 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));
|
||||
|
|
|
@ -19,16 +19,8 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||
MessageField = 0;
|
||||
Timer = 0;
|
||||
BallCapturedFlag = 0;
|
||||
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 407);
|
||||
if (floatArr1)
|
||||
Unknown3 = *floatArr1;
|
||||
else
|
||||
Unknown3 = 0.25;
|
||||
auto floatArr2 = loader::query_float_attribute(groupIndex, 0, 701);
|
||||
if (floatArr2)
|
||||
GravityMult = *floatArr2;
|
||||
else
|
||||
GravityMult = 0.5;
|
||||
Unknown3 = loader::query_float_attribute(groupIndex, 0, 407, 0.25f);
|
||||
GravityMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||
GravityPull = *loader::query_float_attribute(groupIndex, 0, 305);
|
||||
|
||||
loader::query_visual(groupIndex, 0, &visual);
|
||||
|
@ -38,7 +30,8 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||
if (Circle.RadiusSq == 0.0)
|
||||
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);
|
||||
if (tCircle)
|
||||
{
|
||||
|
@ -49,6 +42,10 @@ THole::THole(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||
ZSetValue = loader::query_float_attribute(groupIndex, 0, 408)[2];
|
||||
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 = Circle.RadiusSq;
|
||||
circle.Center.X = Circle.Center.X;
|
||||
|
|
|
@ -48,6 +48,19 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
|||
zMap = ListZMap->Get(0);
|
||||
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{};
|
||||
auto rootBmp = ListBitmap->Get(0);
|
||||
bmp1Rect.XPosition = rootBmp->XPosition - table->XOffset;
|
||||
|
|
|
@ -22,16 +22,8 @@ TRamp::TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
|||
loader::query_visual(groupIndex, 0, &visual);
|
||||
CollisionGroup = visual.CollisionGroup;
|
||||
|
||||
auto floatArr1 = loader::query_float_attribute(groupIndex, 0, 701);
|
||||
if (floatArr1)
|
||||
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;
|
||||
BallFieldMult = loader::query_float_attribute(groupIndex, 0, 701, 0.2f);
|
||||
RampFlag1 = static_cast<int>(loader::query_float_attribute(groupIndex, 0, 1305, 0));
|
||||
|
||||
auto floatArr3Plane = loader::query_float_attribute(groupIndex, 0, 1300);
|
||||
RampPlaneCount = static_cast<int>(floor(*floatArr3Plane));
|
||||
|
|
|
@ -49,11 +49,12 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
|||
PinballTable->GravityAnglY = 1.570796f;
|
||||
}
|
||||
|
||||
auto table3 = PinballTable;
|
||||
GraityDirX = cos(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
||||
GraityDiY = sin(table3->GravityAnglY) * sin(table3->GravityAngleX) * table3->GravityDirVectMult;
|
||||
GraityDirX = cos(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
|
||||
GraityDirY = sin(PinballTable->GravityAnglY) * sin(PinballTable->GravityAngleX) * PinballTable->GravityDirVectMult;
|
||||
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;
|
||||
else
|
||||
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) *
|
||||
ball->Speed * GraityMult;
|
||||
vecDst->Y = GraityDiY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
||||
vecDst->Y = GraityDirY - ball->Acceleration.Y * ball->Speed * GraityMult;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -254,7 +255,7 @@ void TTableLayer::edges_insert_circle(circle_type* circle, TEdgeSegment* edge, f
|
|||
ray.Origin.Y = ray.Origin.Y - edge_manager->AdvanceY;
|
||||
if (maths::ray_intersect_circle(&ray, circle) < 1000000000.0)
|
||||
break;
|
||||
|
||||
|
||||
collision = false;
|
||||
}
|
||||
while (false);
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
float Unknown3F;
|
||||
float Unknown4F;
|
||||
float GraityDirX;
|
||||
float GraityDiY;
|
||||
float GraityDirY;
|
||||
int Unknown7;
|
||||
float GraityMult;
|
||||
field_effect_type Field;
|
||||
|
|
|
@ -185,6 +185,21 @@ int gdrv::create_raw_bitmap(gdrv_bitmap8* bmp, int width, int height, int flag)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ enum class BitmapType : char
|
|||
None = 0,
|
||||
RawBitmap = 1,
|
||||
DibBitmap = 2,
|
||||
Spliced = 4,
|
||||
};
|
||||
|
||||
struct gdrv_bitmap8
|
||||
|
@ -50,6 +51,7 @@ public:
|
|||
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);
|
||||
static int create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size);
|
||||
static int destroy_bitmap(gdrv_bitmap8* bmp);
|
||||
static int display_palette(PALETTEENTRY* plt);
|
||||
static UINT start_blit_sequence();
|
||||
|
|
|
@ -242,6 +242,37 @@ float* loader::query_float_attribute(int groupIndex, int groupIndexOffset, int f
|
|||
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)
|
||||
{
|
||||
if (groupIndex < 0)
|
||||
|
|
|
@ -65,6 +65,7 @@ public:
|
|||
static int query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual);
|
||||
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, float defVal);
|
||||
static __int16* query_iattribute(int groupIndex, int firstValue, int* arraySize);
|
||||
static float play_sound(int soundIndex);
|
||||
static datFileStruct* loader_table;
|
||||
|
|
|
@ -9,8 +9,7 @@ short partman::_field_size[] =
|
|||
2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
|
||||
};
|
||||
|
||||
|
||||
datFileStruct* partman::load_records(LPCSTR lpFileName)
|
||||
datFileStruct* partman::load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode)
|
||||
{
|
||||
_OFSTRUCT ReOpenBuff{};
|
||||
datFileHeader header{};
|
||||
|
@ -86,10 +85,10 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||
if (!groupData)
|
||||
break;
|
||||
|
||||
groupData->EntryCount = entryCount;
|
||||
datEntryData* entryData = groupData->Entries;
|
||||
groupData->EntryCount = 0;
|
||||
for (auto entryIndex = 0; entryIndex < entryCount; ++entryIndex)
|
||||
{
|
||||
auto entryData = &groupData->Entries[groupData->EntryCount];
|
||||
auto entryType = static_cast<datFieldTypes>(_lread_char(fileHandle));
|
||||
entryData->EntryType = entryType;
|
||||
|
||||
|
@ -100,6 +99,12 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||
if (entryType == datFieldTypes::Bitmap8bit)
|
||||
{
|
||||
_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)));
|
||||
entryData->Buffer = reinterpret_cast<char*>(bmp);
|
||||
if (!bmp)
|
||||
|
@ -107,10 +112,15 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||
abort = true;
|
||||
break;
|
||||
}
|
||||
if (bmpHeader.IsFlagSet(bmp8Flags::DibBitmap)
|
||||
? gdrv::create_bitmap(bmp, bmpHeader.Width, bmpHeader.Height)
|
||||
: gdrv::create_raw_bitmap(bmp, bmpHeader.Width, bmpHeader.Height,
|
||||
bmpHeader.IsFlagSet(bmp8Flags::RawBmpUnaligned)))
|
||||
int bmpRez;
|
||||
if (bmpHeader.IsFlagSet(bmp8Flags::Spliced))
|
||||
bmpRez = gdrv::create_spliced_bitmap(bmp, bmpHeader.Width, bmpHeader.Height, bmpHeader.Size);
|
||||
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;
|
||||
break;
|
||||
|
@ -121,9 +131,21 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||
}
|
||||
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));
|
||||
int length = fieldSize - sizeof(dat16BitBmpHeader);
|
||||
|
||||
|
||||
auto zmap = reinterpret_cast<zmap_header_type*>(memory::allocate(sizeof(zmap_header_type) + length));
|
||||
zmap->Width = zMapHeader.Width;
|
||||
zmap->Height = zMapHeader.Height;
|
||||
|
@ -144,9 +166,9 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
|
|||
}
|
||||
|
||||
entryData->FieldSize = fieldSize;
|
||||
datFile->NumberOfGroups = groupIndex + 1;
|
||||
++entryData;
|
||||
groupData->EntryCount++;
|
||||
}
|
||||
datFile->NumberOfGroups = groupIndex + 1;
|
||||
}
|
||||
|
||||
_lclose(fileHandle);
|
||||
|
|
|
@ -28,7 +28,8 @@ enum class datFieldTypes : __int16
|
|||
enum class bmp8Flags : unsigned char
|
||||
{
|
||||
RawBmpUnaligned = 1 << 0,
|
||||
DibBitmap = 1 << 1,
|
||||
DibBitmap = 1 << 1,
|
||||
Spliced = 1 << 2,
|
||||
};
|
||||
|
||||
|
||||
|
@ -71,7 +72,7 @@ struct datFileStruct
|
|||
#pragma pack(1)
|
||||
struct dat8BitBmpHeader
|
||||
{
|
||||
char Unknown1;
|
||||
char Resolution;
|
||||
__int16 Width;
|
||||
__int16 Height;
|
||||
__int16 XPosition;
|
||||
|
@ -108,7 +109,7 @@ static_assert(sizeof(dat16BitBmpHeader) == 14, "Wrong size of zmap_header_type")
|
|||
class partman
|
||||
{
|
||||
public:
|
||||
static datFileStruct* load_records(LPCSTR lpFileName);
|
||||
static datFileStruct* load_records(LPCSTR lpFileName, int resolution, bool fullTiltMode);
|
||||
static void unload_records(datFileStruct* datFile);
|
||||
static char* field_nth(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType, int skipFirstN);
|
||||
static char* field(datFileStruct* datFile, int groupIndex, datFieldTypes entryType);
|
||||
|
|
|
@ -37,8 +37,9 @@ int pb::init()
|
|||
|
||||
++memory::critical_allocation;
|
||||
lstrcpyA(datFileName, winmain::DatFileName);
|
||||
//lstrcpyA(datFileName, "cadet.dat");
|
||||
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;
|
||||
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 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)
|
||||
{
|
||||
memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3);
|
||||
|
@ -545,7 +550,7 @@ void pb::end_game()
|
|||
scores[j] = scores[i];
|
||||
scores[i] = score;
|
||||
|
||||
int index = scoreIndex[j];
|
||||
int index = scoreIndex[j];
|
||||
scoreIndex[j] = scoreIndex[i];
|
||||
scoreIndex[i] = index;
|
||||
}
|
||||
|
|
|
@ -25,4 +25,13 @@
|
|||
/*Sound uses 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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "pch.h"
|
||||
#include "zdrv.h"
|
||||
#include "memory.h"
|
||||
#include "pb.h"
|
||||
|
||||
|
||||
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,
|
||||
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 srcHeightAbs = abs(srcBmp->Height);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,4 +24,6 @@ public:
|
|||
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,
|
||||
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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue