mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-14 11:15:05 -05:00
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:
parent
6ff457eb68
commit
49f6132d23
18 changed files with 205 additions and 48 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,6 +131,18 @@ 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);
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -29,6 +29,7 @@ enum class bmp8Flags : unsigned char
|
|||
{
|
||||
RawBmpUnaligned = 1 << 0,
|
||||
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);
|
||||
|
|
|
@ -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 a new issue