mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 10:37:53 +01:00
Render tweaks part 1: refactored sprite struct.
Optimized sprite handling in render. Fixed switch warning in control.
This commit is contained in:
parent
1e43bdd5fa
commit
9f0ae0434e
23 changed files with 258 additions and 321 deletions
|
@ -52,7 +52,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
||||||
auto zDepth = proj::z_distance(*visVec);
|
auto zDepth = proj::z_distance(*visVec);
|
||||||
VisualZArray[index] = zDepth;
|
VisualZArray[index] = zDepth;
|
||||||
}
|
}
|
||||||
RenderSprite = render::create_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
|
RenderSprite = new render_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
|
||||||
PinballTable->CollisionCompOffset = Offset;
|
PinballTable->CollisionCompOffset = Offset;
|
||||||
Position.Z = Offset;
|
Position.Z = Offset;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,7 @@ void TBall::Repaint()
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bmp = ListBitmap->at(index);
|
auto bmp = ListBitmap->at(index);
|
||||||
render::ball_set(
|
RenderSprite->ball_set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zDepth,
|
zDepth,
|
||||||
pos2D.X - bmp->Width / 2,
|
pos2D.X - bmp->Width / 2,
|
||||||
|
@ -110,7 +109,7 @@ int TBall::Message(MessageCode code, float value)
|
||||||
{
|
{
|
||||||
if (code == MessageCode::Reset)
|
if (code == MessageCode::Reset)
|
||||||
{
|
{
|
||||||
render::ball_set(RenderSprite, nullptr, 0.0, 0, 0);
|
RenderSprite->ball_set(nullptr, 0.0, 0, 0);
|
||||||
Position.X = 0.0;
|
Position.X = 0.0;
|
||||||
CollisionComp = nullptr;
|
CollisionComp = nullptr;
|
||||||
Position.Y = 0.0;
|
Position.Y = 0.0;
|
||||||
|
@ -145,5 +144,5 @@ vector2 TBall::get_coordinates()
|
||||||
void TBall::Disable()
|
void TBall::Disable()
|
||||||
{
|
{
|
||||||
ActiveFlag = false;
|
ActiveFlag = false;
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ TBlocker::TBlocker(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
ActiveFlag = 0;
|
ActiveFlag = 0;
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TBlocker::Message(MessageCode code, float value)
|
int TBlocker::Message(MessageCode code, float value)
|
||||||
|
@ -38,14 +38,14 @@ int TBlocker::Message(MessageCode code, float value)
|
||||||
}
|
}
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
ActiveFlag = 0;
|
ActiveFlag = 0;
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
if (code == MessageCode::TBlockerDisable)
|
if (code == MessageCode::TBlockerDisable)
|
||||||
loader::play_sound(SoundIndex3, this, "TBlocker1");
|
loader::play_sound(SoundIndex3, this, "TBlocker1");
|
||||||
break;
|
break;
|
||||||
case MessageCode::TBlockerEnable:
|
case MessageCode::TBlockerEnable:
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
loader::play_sound(SoundIndex4, this, "TBlocker2");
|
loader::play_sound(SoundIndex4, this, "TBlocker2");
|
||||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
RenderSprite->set_bitmap(ListBitmap->at(0));
|
||||||
if (Timer)
|
if (Timer)
|
||||||
timer::kill(Timer);
|
timer::kill(Timer);
|
||||||
Timer = timer::set(std::max(value, 0.0f), this, TimerExpired);
|
Timer = timer::set(std::max(value, 0.0f), this, TimerExpired);
|
||||||
|
|
|
@ -113,8 +113,7 @@ void TBumper::TimerExpired(int timerId, void* caller)
|
||||||
auto bmp = bump->ListBitmap->at(bump->BmpIndex * 2);
|
auto bmp = bump->ListBitmap->at(bump->BmpIndex * 2);
|
||||||
auto zMap = bump->ListZMap->at(bump->BmpIndex * 2);
|
auto zMap = bump->ListZMap->at(bump->BmpIndex * 2);
|
||||||
bump->Timer = 0;
|
bump->Timer = 0;
|
||||||
render::sprite_set(
|
bump->RenderSprite->set(
|
||||||
bump->RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - bump->PinballTable->XOffset,
|
bmp->XPosition - bump->PinballTable->XOffset,
|
||||||
|
@ -127,8 +126,7 @@ void TBumper::Fire()
|
||||||
int bmpIndex = 2 * BmpIndex + 1;
|
int bmpIndex = 2 * BmpIndex + 1;
|
||||||
auto bmp = ListBitmap->at(bmpIndex);
|
auto bmp = ListBitmap->at(bmpIndex);
|
||||||
auto zMap = ListZMap->at(bmpIndex);
|
auto zMap = ListZMap->at(bmpIndex);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
|
|
@ -62,8 +62,7 @@ int TFlagSpinner::Message(MessageCode code, float value)
|
||||||
BmpIndex = 0;
|
BmpIndex = 0;
|
||||||
auto bmp = ListBitmap->at(0);
|
auto bmp = ListBitmap->at(0);
|
||||||
auto zMap = ListZMap->at(0);
|
auto zMap = ListZMap->at(0);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
@ -113,8 +112,7 @@ void TFlagSpinner::NextFrame()
|
||||||
|
|
||||||
auto bmp = ListBitmap->at(BmpIndex);
|
auto bmp = ListBitmap->at(BmpIndex);
|
||||||
auto zMap = ListZMap->at(BmpIndex);
|
auto zMap = ListZMap->at(BmpIndex);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
|
|
@ -121,8 +121,7 @@ void TFlipper::UpdateSprite(float timeNow)
|
||||||
BmpIndex = newBmpIndex;
|
BmpIndex = newBmpIndex;
|
||||||
auto bmp = ListBitmap->at(BmpIndex);
|
auto bmp = ListBitmap->at(BmpIndex);
|
||||||
auto zMap = ListZMap->at(BmpIndex);
|
auto zMap = ListZMap->at(BmpIndex);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
|
|
@ -14,7 +14,7 @@ TGate::TGate(TPinballTable* table, int groupIndex) : TCollisionComponent(table,
|
||||||
SoundIndex4 = visual.SoundIndex4;
|
SoundIndex4 = visual.SoundIndex4;
|
||||||
SoundIndex3 = visual.SoundIndex3;
|
SoundIndex3 = visual.SoundIndex3;
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
RenderSprite->set_bitmap(ListBitmap->at(0));
|
||||||
control::handler(MessageCode::Reset, this);
|
control::handler(MessageCode::Reset, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@ int TGate::Message(MessageCode code, float value)
|
||||||
{
|
{
|
||||||
case MessageCode::TGateDisable:
|
case MessageCode::TGateDisable:
|
||||||
ActiveFlag = 0;
|
ActiveFlag = 0;
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
loader::play_sound(SoundIndex3, this, "TGate1");
|
loader::play_sound(SoundIndex3, this, "TGate1");
|
||||||
break;
|
break;
|
||||||
case MessageCode::Reset:
|
case MessageCode::Reset:
|
||||||
case MessageCode::TGateEnable:
|
case MessageCode::TGateEnable:
|
||||||
ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
RenderSprite->set_bitmap(ListBitmap->at(0));
|
||||||
if (code == MessageCode::TGateEnable)
|
if (code == MessageCode::TGateEnable)
|
||||||
loader::play_sound(SoundIndex4, this, "TGate2");
|
loader::play_sound(SoundIndex4, this, "TGate2");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,7 +25,7 @@ int TKickback::Message(MessageCode code, float value)
|
||||||
{
|
{
|
||||||
timer::kill(Timer);
|
timer::kill(Timer);
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
KickActiveFlag = 0;
|
KickActiveFlag = 0;
|
||||||
Threshold = 1000000000.0;
|
Threshold = 1000000000.0;
|
||||||
|
@ -67,8 +67,7 @@ void TKickback::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto bmp = kick->ListBitmap->at(1);
|
auto bmp = kick->ListBitmap->at(1);
|
||||||
auto zMap = kick->ListZMap->at(1);
|
auto zMap = kick->ListZMap->at(1);
|
||||||
render::sprite_set(
|
kick->RenderSprite->set(
|
||||||
kick->RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - kick->PinballTable->XOffset,
|
bmp->XPosition - kick->PinballTable->XOffset,
|
||||||
|
@ -81,8 +80,7 @@ void TKickback::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto bmp = kick->ListBitmap->at(0);
|
auto bmp = kick->ListBitmap->at(0);
|
||||||
auto zMap = kick->ListZMap->at(0);
|
auto zMap = kick->ListZMap->at(0);
|
||||||
render::sprite_set(
|
kick->RenderSprite->set(
|
||||||
kick->RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - kick->PinballTable->XOffset,
|
bmp->XPosition - kick->PinballTable->XOffset,
|
||||||
|
|
|
@ -225,7 +225,8 @@ int TLight::Message(MessageCode code, float value)
|
||||||
case MessageCode::TLightFtTmpOverrideOn:
|
case MessageCode::TLightFtTmpOverrideOn:
|
||||||
case MessageCode::TLightFtTmpOverrideOff:
|
case MessageCode::TLightFtTmpOverrideOff:
|
||||||
// FT codes in negative to avoid overlap with 3DPB TLightGroup codes
|
// FT codes in negative to avoid overlap with 3DPB TLightGroup codes
|
||||||
render::sprite_set_bitmap(RenderSprite, BmpArr[code == MessageCode::TLightFtTmpOverrideOn]);
|
if (ListBitmap)
|
||||||
|
RenderSprite->set_bitmap(BmpArr[code == MessageCode::TLightFtTmpOverrideOn]);
|
||||||
if (UndoOverrideTimer)
|
if (UndoOverrideTimer)
|
||||||
timer::kill(UndoOverrideTimer);
|
timer::kill(UndoOverrideTimer);
|
||||||
UndoOverrideTimer = 0;
|
UndoOverrideTimer = 0;
|
||||||
|
@ -240,7 +241,8 @@ int TLight::Message(MessageCode code, float value)
|
||||||
timer::kill(UndoOverrideTimer);
|
timer::kill(UndoOverrideTimer);
|
||||||
UndoOverrideTimer = 0;
|
UndoOverrideTimer = 0;
|
||||||
TemporaryOverrideFlag = false;
|
TemporaryOverrideFlag = false;
|
||||||
render::sprite_set_bitmap(RenderSprite, PreviousBitmap);
|
if (ListBitmap)
|
||||||
|
RenderSprite->set_bitmap(PreviousBitmap);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -267,10 +269,12 @@ void TLight::Reset()
|
||||||
TemporaryOverrideFlag = false;
|
TemporaryOverrideFlag = false;
|
||||||
TurnOffAfterFlashingFg = false;
|
TurnOffAfterFlashingFg = false;
|
||||||
PreviousBitmap = nullptr;
|
PreviousBitmap = nullptr;
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
|
||||||
BmpArr[0] = nullptr;
|
BmpArr[0] = nullptr;
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
|
{
|
||||||
BmpArr[1] = ListBitmap->at(0);
|
BmpArr[1] = ListBitmap->at(0);
|
||||||
|
RenderSprite->set_bitmap(nullptr);
|
||||||
|
}
|
||||||
MessageField = 0;
|
MessageField = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,8 +330,8 @@ void TLight::flasher_start(bool bmpIndex)
|
||||||
void TLight::SetSpriteBmp(gdrv_bitmap8* bmp)
|
void TLight::SetSpriteBmp(gdrv_bitmap8* bmp)
|
||||||
{
|
{
|
||||||
PreviousBitmap = bmp;
|
PreviousBitmap = bmp;
|
||||||
if (!TemporaryOverrideFlag)
|
if (!TemporaryOverrideFlag && RenderSprite)
|
||||||
render::sprite_set_bitmap(RenderSprite, bmp);
|
RenderSprite->set_bitmap(bmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLight::flasher_callback(int timerId, void* caller)
|
void TLight::flasher_callback(int timerId, void* caller)
|
||||||
|
|
|
@ -14,7 +14,7 @@ TLightRollover::TLightRollover(TPinballTable* table, int groupIndex) : TRollover
|
||||||
RolloverFlag = 0;
|
RolloverFlag = 0;
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
if (ListBitmap != nullptr)
|
if (ListBitmap != nullptr)
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
build_walls(groupIndex);
|
build_walls(groupIndex);
|
||||||
FloatArr = *loader::query_float_attribute(groupIndex, 0, 407);
|
FloatArr = *loader::query_float_attribute(groupIndex, 0, 407);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ int TLightRollover::Message(MessageCode code, float value)
|
||||||
timer::kill(Timer);
|
timer::kill(Timer);
|
||||||
Timer = 0;
|
Timer = 0;
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* dire
|
||||||
control::handler(MessageCode::ControlCollision, this);
|
control::handler(MessageCode::ControlCollision, this);
|
||||||
RolloverFlag = RolloverFlag == 0;
|
RolloverFlag = RolloverFlag == 0;
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
RenderSprite->set_bitmap(ListBitmap->at(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,6 @@ void TLightRollover::Collision(TBall* ball, vector2* nextPosition, vector2* dire
|
||||||
void TLightRollover::delay_expired(int timerId, void* caller)
|
void TLightRollover::delay_expired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto roll = static_cast<TLightRollover*>(caller);
|
auto roll = static_cast<TLightRollover*>(caller);
|
||||||
render::sprite_set_bitmap(roll->RenderSprite, nullptr);
|
roll->RenderSprite->set_bitmap(nullptr);
|
||||||
roll->Timer = 0;
|
roll->Timer = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,12 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||||
Control = nullptr;
|
Control = nullptr;
|
||||||
VisualPosNormX= -1.0f;
|
VisualPosNormX= -1.0f;
|
||||||
VisualPosNormY = -1.0f;
|
VisualPosNormY = -1.0f;
|
||||||
|
GroupIndex = groupIndex;
|
||||||
if (table)
|
if (table)
|
||||||
table->ComponentList.push_back(this);
|
table->ComponentList.push_back(this);
|
||||||
if (groupIndex >= 0)
|
if (groupIndex >= 0)
|
||||||
GroupName = loader::query_name(groupIndex);
|
GroupName = loader::query_name(groupIndex);
|
||||||
|
|
||||||
if (loadVisuals && groupIndex >= 0)
|
if (loadVisuals && groupIndex >= 0)
|
||||||
{
|
{
|
||||||
int visualCount = loader::query_visual_states(groupIndex);
|
int visualCount = loader::query_visual_states(groupIndex);
|
||||||
|
@ -37,14 +39,12 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||||
{
|
{
|
||||||
if (!ListBitmap)
|
if (!ListBitmap)
|
||||||
ListBitmap = new std::vector<gdrv_bitmap8*>();
|
ListBitmap = new std::vector<gdrv_bitmap8*>();
|
||||||
if (ListBitmap)
|
|
||||||
ListBitmap->push_back(visual.Bitmap);
|
ListBitmap->push_back(visual.Bitmap);
|
||||||
}
|
}
|
||||||
if (visual.ZMap)
|
if (visual.ZMap)
|
||||||
{
|
{
|
||||||
if (!ListZMap)
|
if (!ListZMap)
|
||||||
ListZMap = new std::vector<zmap_header_type*>();
|
ListZMap = new std::vector<zmap_header_type*>();
|
||||||
if (ListZMap)
|
|
||||||
ListZMap->push_back(visual.ZMap);
|
ListZMap->push_back(visual.ZMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,8 +68,8 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||||
maths::enclosing_box(bmp1Rect, tmpRect, bmp1Rect);
|
maths::enclosing_box(bmp1Rect, tmpRect, bmp1Rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderSprite = render::create_sprite(
|
RenderSprite = new render_sprite(
|
||||||
visualCount > 0 ? VisualTypes::Sprite : VisualTypes::None,
|
VisualTypes::Sprite,
|
||||||
rootBmp,
|
rootBmp,
|
||||||
zMap,
|
zMap,
|
||||||
rootBmp->XPosition - table->XOffset,
|
rootBmp->XPosition - table->XOffset,
|
||||||
|
@ -85,7 +85,6 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
|
||||||
VisualPosNormY = posNorm.Y;
|
VisualPosNormY = posNorm.Y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupIndex = groupIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
struct zmap_header_type;
|
struct zmap_header_type;
|
||||||
struct gdrv_bitmap8;
|
struct gdrv_bitmap8;
|
||||||
struct render_sprite_type_struct;
|
struct render_sprite;
|
||||||
struct component_control;
|
struct component_control;
|
||||||
struct vector2;
|
struct vector2;
|
||||||
class TPinballTable;
|
class TPinballTable;
|
||||||
|
@ -145,7 +145,7 @@ public:
|
||||||
char* GroupName;
|
char* GroupName;
|
||||||
component_control* Control;
|
component_control* Control;
|
||||||
int GroupIndex;
|
int GroupIndex;
|
||||||
render_sprite_type_struct* RenderSprite;
|
render_sprite* RenderSprite;
|
||||||
TPinballTable* PinballTable;
|
TPinballTable* PinballTable;
|
||||||
std::vector<gdrv_bitmap8*>* ListBitmap;
|
std::vector<gdrv_bitmap8*>* ListBitmap;
|
||||||
std::vector<zmap_header_type*>* ListZMap;
|
std::vector<zmap_header_type*>* ListZMap;
|
||||||
|
|
|
@ -133,8 +133,7 @@ int TPlunger::Message(MessageCode code, float value)
|
||||||
loader::play_sound(SoundIndexP2, this, "TPlunger3");
|
loader::play_sound(SoundIndexP2, this, "TPlunger3");
|
||||||
auto bmp = ListBitmap->at(0);
|
auto bmp = ListBitmap->at(0);
|
||||||
auto zMap = ListZMap->at(0);
|
auto zMap = ListZMap->at(0);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
@ -156,8 +155,7 @@ int TPlunger::Message(MessageCode code, float value)
|
||||||
|
|
||||||
auto bmp = ListBitmap->at(0);
|
auto bmp = ListBitmap->at(0);
|
||||||
auto zMap = ListZMap->at(0);
|
auto zMap = ListZMap->at(0);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
@ -204,8 +202,7 @@ void TPlunger::PullbackTimer(int timerId, void* caller)
|
||||||
(plunger->Boost / plunger->MaxPullback)));
|
(plunger->Boost / plunger->MaxPullback)));
|
||||||
auto bmp = plunger->ListBitmap->at(index);
|
auto bmp = plunger->ListBitmap->at(index);
|
||||||
auto zMap = plunger->ListZMap->at(index);
|
auto zMap = plunger->ListZMap->at(index);
|
||||||
render::sprite_set(
|
plunger->RenderSprite->set(
|
||||||
plunger->RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - plunger->PinballTable->XOffset,
|
bmp->XPosition - plunger->PinballTable->XOffset,
|
||||||
|
|
|
@ -20,7 +20,7 @@ int TPopupTarget::Message(MessageCode code, float value)
|
||||||
{
|
{
|
||||||
case MessageCode::TPopupTargetDisable:
|
case MessageCode::TPopupTargetDisable:
|
||||||
ActiveFlag = 0;
|
ActiveFlag = 0;
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
break;
|
break;
|
||||||
case MessageCode::TPopupTargetEnable:
|
case MessageCode::TPopupTargetEnable:
|
||||||
Timer = timer::set(TimerTime, this, TimerExpired);
|
Timer = timer::set(TimerTime, this, TimerExpired);
|
||||||
|
@ -79,7 +79,7 @@ void TPopupTarget::TimerExpired(int timerId, void* caller)
|
||||||
auto target = static_cast<TPopupTarget*>(caller);
|
auto target = static_cast<TPopupTarget*>(caller);
|
||||||
target->Timer = 0;
|
target->Timer = 0;
|
||||||
target->ActiveFlag = 1;
|
target->ActiveFlag = 1;
|
||||||
render::sprite_set_bitmap(target->RenderSprite, target->ListBitmap->at(0));
|
target->RenderSprite->set_bitmap(target->ListBitmap->at(0));
|
||||||
if (timerId)
|
if (timerId)
|
||||||
{
|
{
|
||||||
if (target->SoftHitSoundId)
|
if (target->SoftHitSoundId)
|
||||||
|
|
|
@ -20,7 +20,7 @@ TRollover::TRollover(TPinballTable* table, int groupIndex, bool createWall) : TC
|
||||||
TRollover::TRollover(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
TRollover::TRollover(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false)
|
||||||
{
|
{
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(RenderSprite, ListBitmap->at(0));
|
RenderSprite->set_bitmap(ListBitmap->at(0));
|
||||||
build_walls(groupIndex);
|
build_walls(groupIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ int TRollover::Message(MessageCode code, float value)
|
||||||
{
|
{
|
||||||
if (code == MessageCode::Reset)
|
if (code == MessageCode::Reset)
|
||||||
{
|
{
|
||||||
this->ActiveFlag = 1;
|
ActiveFlag = 1;
|
||||||
this->RolloverFlag = 0;
|
RolloverFlag = 0;
|
||||||
if (this->ListBitmap)
|
if (ListBitmap)
|
||||||
render::sprite_set_bitmap(this->RenderSprite, this->ListBitmap->at(0));
|
RenderSprite->set_bitmap(ListBitmap->at(0));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ void TRollover::Collision(TBall* ball, vector2* nextPosition, vector2* direction
|
||||||
{
|
{
|
||||||
if (!RolloverFlag)
|
if (!RolloverFlag)
|
||||||
bmp = ListBitmap->at(0);
|
bmp = ListBitmap->at(0);
|
||||||
render::sprite_set_bitmap(RenderSprite, bmp);
|
RenderSprite->set_bitmap(bmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,7 @@ int TSoloTarget::Message(MessageCode code, float value)
|
||||||
auto index = 1 - ActiveFlag;
|
auto index = 1 - ActiveFlag;
|
||||||
auto bmp = ListBitmap->at(index);
|
auto bmp = ListBitmap->at(index);
|
||||||
auto zMap = ListZMap->at(index);
|
auto zMap = ListZMap->at(index);
|
||||||
render::sprite_set(
|
RenderSprite->set(
|
||||||
RenderSprite,
|
|
||||||
bmp,
|
bmp,
|
||||||
zMap,
|
zMap,
|
||||||
bmp->XPosition - PinballTable->XOffset,
|
bmp->XPosition - PinballTable->XOffset,
|
||||||
|
|
|
@ -32,7 +32,7 @@ TTableLayer::TTableLayer(TPinballTable* table): TCollisionComponent(table, -1, f
|
||||||
rect.YPosition = 0;
|
rect.YPosition = 0;
|
||||||
rect.Width = bmp->Width;
|
rect.Width = bmp->Width;
|
||||||
rect.Height = bmp->Height;
|
rect.Height = bmp->Height;
|
||||||
render::create_sprite(VisualTypes::None, bmp, visual.ZMap, 0, 0, &rect);
|
new render_sprite(VisualTypes::Background, bmp, visual.ZMap, 0, 0, &rect);
|
||||||
|
|
||||||
PinballTable->SoundIndex1 = visual.SoundIndex4;
|
PinballTable->SoundIndex1 = visual.SoundIndex4;
|
||||||
PinballTable->SoundIndex2 = visual.SoundIndex3;
|
PinballTable->SoundIndex2 = visual.SoundIndex3;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TWall::TWall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
{
|
{
|
||||||
if (RenderSprite)
|
if (RenderSprite)
|
||||||
render::sprite_set_bitmap(RenderSprite, nullptr);
|
RenderSprite->set_bitmap(nullptr);
|
||||||
if (ListBitmap)
|
if (ListBitmap)
|
||||||
BmpPtr = ListBitmap->at(0);
|
BmpPtr = ListBitmap->at(0);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ void TWall::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
||||||
{
|
{
|
||||||
if (BmpPtr)
|
if (BmpPtr)
|
||||||
{
|
{
|
||||||
render::sprite_set_bitmap(RenderSprite, BmpPtr);
|
RenderSprite->set_bitmap(BmpPtr);
|
||||||
Timer = timer::set(0.1f, this, TimerExpired);
|
Timer = timer::set(0.1f, this, TimerExpired);
|
||||||
}
|
}
|
||||||
control::handler(MessageCode::ControlCollision, this);
|
control::handler(MessageCode::ControlCollision, this);
|
||||||
|
@ -40,7 +40,7 @@ void TWall::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
||||||
void TWall::TimerExpired(int timerId, void* caller)
|
void TWall::TimerExpired(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto wall = static_cast<TWall*>(caller);
|
auto wall = static_cast<TWall*>(caller);
|
||||||
render::sprite_set_bitmap(wall->RenderSprite, nullptr);
|
wall->RenderSprite->set_bitmap(nullptr);
|
||||||
wall->Timer = 0;
|
wall->Timer = 0;
|
||||||
wall->MessageField = 0;
|
wall->MessageField = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2081,6 +2081,7 @@ void control::GravityWellKickoutControl(MessageCode code, TPinballComponent* cal
|
||||||
case MessageCode::Reset:
|
case MessageCode::Reset:
|
||||||
kickout1->ActiveFlag = 0;
|
kickout1->ActiveFlag = 0;
|
||||||
break;
|
break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ TTextBox *pb::InfoTextBox, *pb::MissTextBox;
|
||||||
|
|
||||||
int pb::init()
|
int pb::init()
|
||||||
{
|
{
|
||||||
float projMat[12], zMin = 0, zScaler = 0;
|
float projMat[12];
|
||||||
|
|
||||||
if (DatFileName.empty())
|
if (DatFileName.empty())
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -75,12 +75,12 @@ int pb::init()
|
||||||
auto projCenterX = resInfo->TableWidth * 0.5f;
|
auto projCenterX = resInfo->TableWidth * 0.5f;
|
||||||
auto projCenterY = resInfo->TableHeight * 0.5f;
|
auto projCenterY = resInfo->TableHeight * 0.5f;
|
||||||
auto projD = cameraInfo[0];
|
auto projD = cameraInfo[0];
|
||||||
proj::init(projMat, projD, projCenterX, projCenterY);
|
auto zMin = cameraInfo[1];
|
||||||
zMin = cameraInfo[1];
|
auto zScaler = cameraInfo[2];
|
||||||
zScaler = cameraInfo[2];
|
proj::init(projMat, projD, projCenterX, projCenterY, zMin, zScaler);
|
||||||
}
|
}
|
||||||
|
|
||||||
render::init(nullptr, zMin, zScaler, resInfo->TableWidth, resInfo->TableHeight);
|
render::init(nullptr, resInfo->TableWidth, resInfo->TableHeight);
|
||||||
gdrv::copy_bitmap(
|
gdrv::copy_bitmap(
|
||||||
render::vscreen,
|
render::vscreen,
|
||||||
backgroundBmp->Width,
|
backgroundBmp->Width,
|
||||||
|
|
|
@ -3,17 +3,10 @@
|
||||||
|
|
||||||
mat4_row_major proj::matrix;
|
mat4_row_major proj::matrix;
|
||||||
float proj::d_, proj::centerx, proj::centery;
|
float proj::d_, proj::centerx, proj::centery;
|
||||||
|
float proj::zscaler, proj::zmin, proj::zmax;
|
||||||
|
|
||||||
void proj::init(float* mat4x3, float d, float centerX, float centerY)
|
void proj::init(float* mat4x3, float d, float centerX, float centerY, float zMin, float zScaler)
|
||||||
{
|
{
|
||||||
/*for (auto colIndex = 0; colIndex < 4; ++colIndex)
|
|
||||||
{
|
|
||||||
// Todo: out of bounds read from mat4x3?
|
|
||||||
for (int rowIndex = colIndex, i = 4; i > 0; rowIndex += 4, --i)
|
|
||||||
{
|
|
||||||
((float*)&matrix)[rowIndex] = mat4x3[rowIndex];
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
memcpy(&matrix, mat4x3, sizeof(float) * 4 * 3);
|
memcpy(&matrix, mat4x3, sizeof(float) * 4 * 3);
|
||||||
|
|
||||||
matrix.Row3.X = 0.0;
|
matrix.Row3.X = 0.0;
|
||||||
|
@ -24,6 +17,10 @@ void proj::init(float* mat4x3, float d, float centerX, float centerY)
|
||||||
d_ = d;
|
d_ = d;
|
||||||
centerx = centerX;
|
centerx = centerX;
|
||||||
centery = centerY;
|
centery = centerY;
|
||||||
|
|
||||||
|
zscaler = zScaler;
|
||||||
|
zmin = zMin;
|
||||||
|
zmax = static_cast<float>(0xffFFffFF) / zScaler + zMin;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector3 proj::matrix_vector_multiply(const mat4_row_major& mat, const vector3& vec)
|
vector3 proj::matrix_vector_multiply(const mat4_row_major& mat, const vector3& vec)
|
||||||
|
@ -103,3 +100,17 @@ void proj::recenter(float centerX, float centerY)
|
||||||
centerx = centerX;
|
centerx = centerX;
|
||||||
centery = centerY;
|
centery = centerY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t proj::NormalizeDepth(float depth)
|
||||||
|
{
|
||||||
|
uint16_t result = 0;
|
||||||
|
if (depth >= zmin)
|
||||||
|
{
|
||||||
|
auto depthScaled = (depth - zmin) * zscaler;
|
||||||
|
if (depthScaled <= zmax)
|
||||||
|
result = static_cast<uint16_t>(depthScaled);
|
||||||
|
else
|
||||||
|
result = 0xffFF;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -21,14 +21,16 @@ struct mat4_row_major
|
||||||
class proj
|
class proj
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void init(float* mat4x3, float d, float centerX, float centerY);
|
static void init(float* mat4x3, float d, float centerX, float centerY, float zMin, float zScaler);
|
||||||
static vector3 matrix_vector_multiply(const mat4_row_major& mat, const vector3& vec);
|
static vector3 matrix_vector_multiply(const mat4_row_major& mat, const vector3& vec);
|
||||||
static float z_distance(const vector3& vec);
|
static float z_distance(const vector3& vec);
|
||||||
static vector2i xform_to_2d(const vector3& vec);
|
static vector2i xform_to_2d(const vector3& vec);
|
||||||
static vector2i xform_to_2d(const vector2& vec);
|
static vector2i xform_to_2d(const vector2& vec);
|
||||||
static vector3 ReverseXForm(const vector2i& vec);
|
static vector3 ReverseXForm(const vector2i& vec);
|
||||||
static void recenter(float centerX, float centerY);
|
static void recenter(float centerX, float centerY);
|
||||||
|
static uint16_t NormalizeDepth(float depth);
|
||||||
private:
|
private:
|
||||||
static mat4_row_major matrix;
|
static mat4_row_major matrix;
|
||||||
static float d_, centerx, centery;
|
static float d_, centerx, centery;
|
||||||
|
static float zscaler, zmin, zmax;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,21 +9,95 @@
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "winmain.h"
|
#include "winmain.h"
|
||||||
#include "DebugOverlay.h"
|
#include "DebugOverlay.h"
|
||||||
|
#include "proj.h"
|
||||||
|
|
||||||
std::vector<render_sprite_type_struct*> render::dirty_list, render::sprite_list, render::ball_list;
|
std::vector<render_sprite*> render::sprite_list, render::ball_list;
|
||||||
zmap_header_type* render::background_zmap;
|
zmap_header_type* render::background_zmap;
|
||||||
int render::zmap_offset, render::zmap_offsetY, render::offset_x, render::offset_y;
|
int render::zmap_offsetX, render::zmap_offsetY, render::offset_x, render::offset_y;
|
||||||
float render::zscaler, render::zmin, render::zmax;
|
|
||||||
rectangle_type render::vscreen_rect;
|
rectangle_type render::vscreen_rect;
|
||||||
gdrv_bitmap8 *render::vscreen, *render::background_bitmap, *render::ball_bitmap[20];
|
gdrv_bitmap8 *render::vscreen, *render::background_bitmap, *render::ball_bitmap[20];
|
||||||
zmap_header_type* render::zscreen;
|
zmap_header_type* render::zscreen;
|
||||||
SDL_Rect render::DestinationRect{};
|
SDL_Rect render::DestinationRect{};
|
||||||
|
|
||||||
void render::init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int height)
|
render_sprite::render_sprite(VisualTypes visualType, gdrv_bitmap8* bmp, zmap_header_type* zMap,
|
||||||
|
int xPosition, int yPosition, rectangle_type* boundingRect)
|
||||||
|
{
|
||||||
|
Bmp = bmp;
|
||||||
|
ZMap = zMap;
|
||||||
|
VisualType = visualType;
|
||||||
|
DeleteFlag = false;
|
||||||
|
OccludedSprites = nullptr;
|
||||||
|
DirtyRect = rectangle_type{};
|
||||||
|
DirtyFlag = visualType != VisualTypes::Ball;
|
||||||
|
ZMapOffestX = 0;
|
||||||
|
ZMapOffestY = 0;
|
||||||
|
Depth = 0xffFF;
|
||||||
|
|
||||||
|
if (boundingRect)
|
||||||
|
{
|
||||||
|
BoundingRect = *boundingRect;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BoundingRect.Width = -1;
|
||||||
|
BoundingRect.Height = -1;
|
||||||
|
BoundingRect.XPosition = 0;
|
||||||
|
BoundingRect.YPosition = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BmpRect.YPosition = yPosition;
|
||||||
|
BmpRect.XPosition = xPosition;
|
||||||
|
if (bmp)
|
||||||
|
{
|
||||||
|
BmpRect.Width = bmp->Width;
|
||||||
|
BmpRect.Height = bmp->Height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BmpRect.Width = 0;
|
||||||
|
BmpRect.Height = 0;
|
||||||
|
}
|
||||||
|
DirtyRectPrev = BmpRect;
|
||||||
|
|
||||||
|
render::AddSprite(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_sprite::~render_sprite()
|
||||||
|
{
|
||||||
|
render::RemoveSprite(*this);
|
||||||
|
delete OccludedSprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_sprite::set(gdrv_bitmap8* bmp, zmap_header_type* zMap, int xPos, int yPos)
|
||||||
|
{
|
||||||
|
if (Bmp == bmp && ZMap == zMap && BmpRect.XPosition == xPos && BmpRect.YPosition == yPos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Bmp = bmp;
|
||||||
|
ZMap = zMap;
|
||||||
|
DirtyFlag = VisualType != VisualTypes::Ball;
|
||||||
|
BmpRect.XPosition = xPos;
|
||||||
|
BmpRect.YPosition = yPos;
|
||||||
|
if (bmp)
|
||||||
|
{
|
||||||
|
BmpRect.Width = bmp->Width;
|
||||||
|
BmpRect.Height = bmp->Height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_sprite::set_bitmap(gdrv_bitmap8* bmp)
|
||||||
|
{
|
||||||
|
set(bmp, ZMap, BmpRect.XPosition, BmpRect.YPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_sprite::ball_set(gdrv_bitmap8* bmp, float depth, int xPos, int yPos)
|
||||||
|
{
|
||||||
|
set(bmp, ZMap,xPos, yPos);
|
||||||
|
Depth = proj::NormalizeDepth(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void render::init(gdrv_bitmap8* bmp, int width, int height)
|
||||||
{
|
{
|
||||||
zscaler = zScaler;
|
|
||||||
zmin = zMin;
|
|
||||||
zmax = 4294967300.0f / zScaler + zMin;
|
|
||||||
vscreen = new gdrv_bitmap8(width, height, false);
|
vscreen = new gdrv_bitmap8(width, height, false);
|
||||||
zscreen = new zmap_header_type(width, height, width);
|
zscreen = new zmap_header_type(width, height, width);
|
||||||
zdrv::fill(zscreen, zscreen->Width, zscreen->Height, 0, 0, 0xFFFF);
|
zdrv::fill(zscreen, zscreen->Width, zscreen->Height, 0, 0, 0xFFFF);
|
||||||
|
@ -49,15 +123,12 @@ void render::uninit()
|
||||||
{
|
{
|
||||||
delete vscreen;
|
delete vscreen;
|
||||||
delete zscreen;
|
delete zscreen;
|
||||||
for (auto sprite : sprite_list)
|
|
||||||
remove_sprite(sprite, false);
|
// Sprite destructor removes it from the list.
|
||||||
for (auto ball : ball_list)
|
while (!sprite_list.empty())
|
||||||
remove_ball(ball, false);
|
delete sprite_list[0];
|
||||||
for (auto& ballBmp : ball_bitmap)
|
while (!ball_list.empty())
|
||||||
delete ballBmp;
|
delete ball_list[0];
|
||||||
ball_list.clear();
|
|
||||||
dirty_list.clear();
|
|
||||||
sprite_list.clear();
|
|
||||||
DebugOverlay::UnInit();
|
DebugOverlay::UnInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,35 +142,38 @@ void render::update()
|
||||||
unpaint_balls();
|
unpaint_balls();
|
||||||
|
|
||||||
// Clip dirty sprites with vScreen, clear clipping (dirty) rectangles
|
// Clip dirty sprites with vScreen, clear clipping (dirty) rectangles
|
||||||
for (auto curSprite : dirty_list)
|
for (const auto sprite : sprite_list)
|
||||||
{
|
{
|
||||||
|
if (!sprite->DirtyFlag)
|
||||||
|
continue;
|
||||||
|
|
||||||
bool clearSprite = false;
|
bool clearSprite = false;
|
||||||
switch (curSprite->VisualType)
|
switch (sprite->VisualType)
|
||||||
{
|
{
|
||||||
case VisualTypes::Sprite:
|
case VisualTypes::Sprite:
|
||||||
if (curSprite->DirtyRectPrev.Width > 0)
|
if (sprite->DirtyRectPrev.Width > 0)
|
||||||
maths::enclosing_box(curSprite->DirtyRectPrev, curSprite->BmpRect, curSprite->DirtyRect);
|
maths::enclosing_box(sprite->DirtyRectPrev, sprite->BmpRect, sprite->DirtyRect);
|
||||||
|
|
||||||
if (maths::rectangle_clip(curSprite->DirtyRect, vscreen_rect, &curSprite->DirtyRect))
|
if (maths::rectangle_clip(sprite->DirtyRect, vscreen_rect, &sprite->DirtyRect))
|
||||||
clearSprite = true;
|
clearSprite = true;
|
||||||
else
|
else
|
||||||
curSprite->DirtyRect.Width = -1;
|
sprite->DirtyRect.Width = -1;
|
||||||
break;
|
break;
|
||||||
case VisualTypes::None:
|
case VisualTypes::Background:
|
||||||
if (maths::rectangle_clip(curSprite->BmpRect, vscreen_rect, &curSprite->DirtyRect))
|
if (maths::rectangle_clip(sprite->BmpRect, vscreen_rect, &sprite->DirtyRect))
|
||||||
clearSprite = !curSprite->Bmp;
|
clearSprite = !sprite->Bmp;
|
||||||
else
|
else
|
||||||
curSprite->DirtyRect.Width = -1;
|
sprite->DirtyRect.Width = -1;
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearSprite)
|
if (clearSprite)
|
||||||
{
|
{
|
||||||
auto yPos = curSprite->DirtyRect.YPosition;
|
auto yPos = sprite->DirtyRect.YPosition;
|
||||||
auto width = curSprite->DirtyRect.Width;
|
auto width = sprite->DirtyRect.Width;
|
||||||
auto xPos = curSprite->DirtyRect.XPosition;
|
auto xPos = sprite->DirtyRect.XPosition;
|
||||||
auto height = curSprite->DirtyRect.Height;
|
auto height = sprite->DirtyRect.Height;
|
||||||
zdrv::fill(zscreen, width, height, xPos, yPos, 0xFFFF);
|
zdrv::fill(zscreen, width, height, xPos, yPos, 0xFFFF);
|
||||||
if (background_bitmap)
|
if (background_bitmap)
|
||||||
gdrv::copy_bitmap(vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
|
gdrv::copy_bitmap(vscreen, width, height, xPos, yPos, background_bitmap, xPos, yPos);
|
||||||
|
@ -109,191 +183,60 @@ void render::update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paint dirty rectangles of dirty sprites
|
// Paint dirty rectangles of dirty sprites
|
||||||
for (auto sprite : dirty_list)
|
for (auto sprite : sprite_list)
|
||||||
{
|
{
|
||||||
if (sprite->DirtyRect.Width > 0 && (sprite->VisualType == VisualTypes::None || sprite->VisualType ==
|
if (!sprite->DirtyFlag)
|
||||||
VisualTypes::Sprite))
|
continue;
|
||||||
repaint(sprite);
|
|
||||||
|
repaint(*sprite);
|
||||||
|
sprite->DirtyFlag = false;
|
||||||
|
sprite->DirtyRectPrev = sprite->DirtyRect;
|
||||||
|
if (sprite->DeleteFlag)
|
||||||
|
delete sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
paint_balls();
|
paint_balls();
|
||||||
|
|
||||||
// In the original, this used to blit dirty sprites and balls
|
|
||||||
for (auto sprite : dirty_list)
|
|
||||||
{
|
|
||||||
sprite->DirtyRectPrev = sprite->DirtyRect;
|
|
||||||
if (sprite->UnknownFlag != 0)
|
|
||||||
remove_sprite(sprite, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
dirty_list.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::sprite_modified(render_sprite_type_struct* sprite)
|
void render::AddSprite(render_sprite& sprite)
|
||||||
{
|
{
|
||||||
if (sprite->VisualType != VisualTypes::Ball && dirty_list.size() < 999)
|
if (!sprite.ZMap && sprite.VisualType != VisualTypes::Ball)
|
||||||
dirty_list.push_back(sprite);
|
{
|
||||||
|
sprite.ZMap = background_zmap;
|
||||||
|
sprite.ZMapOffestY = sprite.BmpRect.XPosition - zmap_offsetX;
|
||||||
|
sprite.ZMapOffestX = sprite.BmpRect.YPosition - zmap_offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& list = sprite.VisualType == VisualTypes::Ball ? ball_list : sprite_list;
|
||||||
|
list.push_back(&sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
render_sprite_type_struct* render::create_sprite(VisualTypes visualType, gdrv_bitmap8* bmp, zmap_header_type* zMap,
|
void render::RemoveSprite(render_sprite& sprite)
|
||||||
int xPosition, int yPosition, rectangle_type* rect)
|
|
||||||
{
|
{
|
||||||
auto sprite = new render_sprite_type_struct();
|
auto& list = sprite.VisualType == VisualTypes::Ball ? ball_list : sprite_list;
|
||||||
if (!sprite)
|
auto it = std::find(list.begin(), list.end(), &sprite);
|
||||||
return nullptr;
|
if (it != list.end())
|
||||||
sprite->BmpRect.YPosition = yPosition;
|
list.erase(it);
|
||||||
sprite->BmpRect.XPosition = xPosition;
|
|
||||||
sprite->Bmp = bmp;
|
|
||||||
sprite->VisualType = visualType;
|
|
||||||
sprite->UnknownFlag = 0;
|
|
||||||
sprite->SpriteArray = nullptr;
|
|
||||||
sprite->DirtyRect = rectangle_type{};
|
|
||||||
if (rect)
|
|
||||||
{
|
|
||||||
sprite->BoundingRect = *rect;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite->BoundingRect.Width = -1;
|
|
||||||
sprite->BoundingRect.Height = -1;
|
|
||||||
sprite->BoundingRect.XPosition = 0;
|
|
||||||
sprite->BoundingRect.YPosition = 0;
|
|
||||||
}
|
|
||||||
if (bmp)
|
|
||||||
{
|
|
||||||
sprite->BmpRect.Width = bmp->Width;
|
|
||||||
sprite->BmpRect.Height = bmp->Height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite->BmpRect.Width = 0;
|
|
||||||
sprite->BmpRect.Height = 0;
|
|
||||||
}
|
|
||||||
sprite->ZMap = zMap;
|
|
||||||
sprite->ZMapOffestX = 0;
|
|
||||||
sprite->ZMapOffestY = 0;
|
|
||||||
if (!zMap && visualType != VisualTypes::Ball)
|
|
||||||
{
|
|
||||||
sprite->ZMap = background_zmap;
|
|
||||||
sprite->ZMapOffestY = xPosition - zmap_offset;
|
|
||||||
sprite->ZMapOffestX = yPosition - zmap_offsetY;
|
|
||||||
}
|
|
||||||
sprite->DirtyRectPrev = sprite->BmpRect;
|
|
||||||
if (visualType == VisualTypes::Ball)
|
|
||||||
{
|
|
||||||
ball_list.push_back(sprite);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite_list.push_back(sprite);
|
|
||||||
sprite_modified(sprite);
|
|
||||||
}
|
|
||||||
return sprite;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void render::set_background_zmap(zmap_header_type* zMap, int offsetX, int offsetY)
|
||||||
void render::remove_sprite(render_sprite_type_struct* sprite, bool removeFromList)
|
|
||||||
{
|
|
||||||
if (removeFromList)
|
|
||||||
{
|
|
||||||
auto it = std::find(sprite_list.begin(), sprite_list.end(), sprite);
|
|
||||||
if (it != sprite_list.end())
|
|
||||||
sprite_list.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete sprite->SpriteArray;
|
|
||||||
delete sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
void render::remove_ball(render_sprite_type_struct* ball, bool removeFromList)
|
|
||||||
{
|
|
||||||
if (removeFromList)
|
|
||||||
{
|
|
||||||
auto it = std::find(ball_list.begin(), ball_list.end(), ball);
|
|
||||||
if (it != ball_list.end())
|
|
||||||
ball_list.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete ball->SpriteArray;
|
|
||||||
delete ball;
|
|
||||||
}
|
|
||||||
|
|
||||||
void render::sprite_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, zmap_header_type* zMap, int xPos,
|
|
||||||
int yPos)
|
|
||||||
{
|
|
||||||
if (sprite)
|
|
||||||
{
|
|
||||||
sprite->BmpRect.XPosition = xPos;
|
|
||||||
sprite->BmpRect.YPosition = yPos;
|
|
||||||
sprite->Bmp = bmp;
|
|
||||||
if (bmp)
|
|
||||||
{
|
|
||||||
sprite->BmpRect.Width = bmp->Width;
|
|
||||||
sprite->BmpRect.Height = bmp->Height;
|
|
||||||
}
|
|
||||||
sprite->ZMap = zMap;
|
|
||||||
sprite_modified(sprite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void render::sprite_set_bitmap(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp)
|
|
||||||
{
|
|
||||||
if (sprite && sprite->Bmp != bmp)
|
|
||||||
{
|
|
||||||
sprite->Bmp = bmp;
|
|
||||||
if (bmp)
|
|
||||||
{
|
|
||||||
sprite->BmpRect.Width = bmp->Width;
|
|
||||||
sprite->BmpRect.Height = bmp->Height;
|
|
||||||
}
|
|
||||||
sprite_modified(sprite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void render::set_background_zmap(struct zmap_header_type* zMap, int offsetX, int offsetY)
|
|
||||||
{
|
{
|
||||||
background_zmap = zMap;
|
background_zmap = zMap;
|
||||||
zmap_offset = offsetX;
|
zmap_offsetX = offsetX;
|
||||||
zmap_offsetY = offsetY;
|
zmap_offsetY = offsetY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render::ball_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, float depth, int xPos, int yPos)
|
void render::repaint(const render_sprite& sprite)
|
||||||
{
|
|
||||||
if (sprite)
|
|
||||||
{
|
|
||||||
sprite->Bmp = bmp;
|
|
||||||
if (bmp)
|
|
||||||
{
|
|
||||||
sprite->BmpRect.XPosition = xPos;
|
|
||||||
sprite->BmpRect.YPosition = yPos;
|
|
||||||
sprite->BmpRect.Width = bmp->Width;
|
|
||||||
sprite->BmpRect.Height = bmp->Height;
|
|
||||||
}
|
|
||||||
if (depth >= zmin)
|
|
||||||
{
|
|
||||||
float depth2 = (depth - zmin) * zscaler;
|
|
||||||
if (depth2 <= zmax)
|
|
||||||
sprite->Depth = static_cast<short>(depth2);
|
|
||||||
else
|
|
||||||
sprite->Depth = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprite->Depth = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void render::repaint(struct render_sprite_type_struct* sprite)
|
|
||||||
{
|
{
|
||||||
rectangle_type clipRect{};
|
rectangle_type clipRect{};
|
||||||
if (!sprite->SpriteArray)
|
if (!sprite.OccludedSprites || sprite.VisualType == VisualTypes::Ball || sprite.DirtyRect.Width <= 0)
|
||||||
return;
|
return;
|
||||||
for (auto refSprite : *sprite->SpriteArray)
|
|
||||||
|
for (auto refSprite : *sprite.OccludedSprites)
|
||||||
{
|
{
|
||||||
if (!refSprite->UnknownFlag && refSprite->Bmp)
|
if (!refSprite->DeleteFlag && refSprite->Bmp)
|
||||||
{
|
{
|
||||||
if (maths::rectangle_clip(refSprite->BmpRect, sprite->DirtyRect, &clipRect))
|
if (maths::rectangle_clip(refSprite->BmpRect, sprite.DirtyRect, &clipRect))
|
||||||
zdrv::paint(
|
zdrv::paint(
|
||||||
clipRect.Width,
|
clipRect.Width,
|
||||||
clipRect.Height,
|
clipRect.Height,
|
||||||
|
@ -316,20 +259,11 @@ void render::repaint(struct render_sprite_type_struct* sprite)
|
||||||
|
|
||||||
void render::paint_balls()
|
void render::paint_balls()
|
||||||
{
|
{
|
||||||
// Sort ball sprites by depth
|
// Sort ball sprites by ascending depth
|
||||||
for (auto i = 0u; i < ball_list.size(); i++)
|
std::sort(ball_list.begin(), ball_list.end(), [](const render_sprite* lhs, const render_sprite* rhs)
|
||||||
{
|
{
|
||||||
for (auto j = i; j < ball_list.size() / 2; ++j)
|
return lhs->Depth < rhs->Depth;
|
||||||
{
|
});
|
||||||
auto ballA = ball_list[j];
|
|
||||||
auto ballB = ball_list[i];
|
|
||||||
if (ballB->Depth > ballA->Depth)
|
|
||||||
{
|
|
||||||
ball_list[i] = ballA;
|
|
||||||
ball_list[j] = ballB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For balls that clip vScreen: save original vScreen contents and paint ball bitmap.
|
// For balls that clip vScreen: save original vScreen contents and paint ball bitmap.
|
||||||
for (auto index = 0u; index < ball_list.size(); ++index)
|
for (auto index = 0u; index < ball_list.size(); ++index)
|
||||||
|
@ -391,26 +325,25 @@ void render::shift(int offsetX, int offsetY)
|
||||||
|
|
||||||
void render::build_occlude_list()
|
void render::build_occlude_list()
|
||||||
{
|
{
|
||||||
std::vector<render_sprite_type_struct*>* spriteArr = nullptr;
|
std::vector<render_sprite*>* spriteArr = nullptr;
|
||||||
for (auto mainSprite : sprite_list)
|
for (auto mainSprite : sprite_list)
|
||||||
{
|
{
|
||||||
if (mainSprite->SpriteArray)
|
if (mainSprite->OccludedSprites)
|
||||||
{
|
{
|
||||||
delete mainSprite->SpriteArray;
|
delete mainSprite->OccludedSprites;
|
||||||
mainSprite->SpriteArray = nullptr;
|
mainSprite->OccludedSprites = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mainSprite->UnknownFlag && mainSprite->BoundingRect.Width != -1)
|
if (!mainSprite->DeleteFlag && mainSprite->BoundingRect.Width != -1)
|
||||||
{
|
{
|
||||||
if (!spriteArr)
|
if (!spriteArr)
|
||||||
spriteArr = new std::vector<render_sprite_type_struct*>();
|
spriteArr = new std::vector<render_sprite*>();
|
||||||
|
|
||||||
for (auto refSprite : sprite_list)
|
for (auto refSprite : sprite_list)
|
||||||
{
|
{
|
||||||
if (!refSprite->UnknownFlag
|
if (!refSprite->DeleteFlag
|
||||||
&& refSprite->BoundingRect.Width != -1
|
&& refSprite->BoundingRect.Width != -1
|
||||||
&& maths::rectangle_clip(mainSprite->BoundingRect, refSprite->BoundingRect, nullptr)
|
&& maths::rectangle_clip(mainSprite->BoundingRect, refSprite->BoundingRect, nullptr))
|
||||||
&& spriteArr)
|
|
||||||
{
|
{
|
||||||
spriteArr->push_back(refSprite);
|
spriteArr->push_back(refSprite);
|
||||||
}
|
}
|
||||||
|
@ -420,7 +353,7 @@ void render::build_occlude_list()
|
||||||
spriteArr->clear();
|
spriteArr->clear();
|
||||||
if (!spriteArr->empty())
|
if (!spriteArr->empty())
|
||||||
{
|
{
|
||||||
mainSprite->SpriteArray = spriteArr;
|
mainSprite->OccludedSprites = spriteArr;
|
||||||
spriteArr = nullptr;
|
spriteArr = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,25 +5,33 @@
|
||||||
|
|
||||||
enum class VisualTypes : char
|
enum class VisualTypes : char
|
||||||
{
|
{
|
||||||
None = 0,
|
Background = 0,
|
||||||
Sprite = 1,
|
Sprite = 1,
|
||||||
Ball = 2
|
Ball = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct render_sprite_type_struct
|
struct render_sprite
|
||||||
{
|
{
|
||||||
rectangle_type BmpRect;
|
rectangle_type BmpRect{};
|
||||||
gdrv_bitmap8* Bmp;
|
gdrv_bitmap8* Bmp;
|
||||||
zmap_header_type* ZMap;
|
zmap_header_type* ZMap;
|
||||||
char UnknownFlag;
|
bool DeleteFlag;
|
||||||
VisualTypes VisualType;
|
VisualTypes VisualType;
|
||||||
int16_t Depth;
|
uint16_t Depth;
|
||||||
rectangle_type DirtyRectPrev;
|
rectangle_type DirtyRectPrev{};
|
||||||
int ZMapOffestY;
|
int ZMapOffestY;
|
||||||
int ZMapOffestX;
|
int ZMapOffestX;
|
||||||
rectangle_type DirtyRect;
|
rectangle_type DirtyRect{};
|
||||||
std::vector<render_sprite_type_struct*>* SpriteArray;
|
std::vector<render_sprite*>* OccludedSprites;
|
||||||
rectangle_type BoundingRect;
|
rectangle_type BoundingRect{};
|
||||||
|
bool DirtyFlag{};
|
||||||
|
|
||||||
|
render_sprite(VisualTypes visualType, gdrv_bitmap8* bmp, zmap_header_type* zMap,
|
||||||
|
int xPosition, int yPosition, rectangle_type* boundingRect);
|
||||||
|
~render_sprite();
|
||||||
|
void set(gdrv_bitmap8* bmp, zmap_header_type* zMap, int xPos, int yPos);
|
||||||
|
void set_bitmap(gdrv_bitmap8* bmp);
|
||||||
|
void ball_set(gdrv_bitmap8* bmp, float depth, int xPos, int yPos);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,35 +41,26 @@ public:
|
||||||
static gdrv_bitmap8 *vscreen, *background_bitmap;
|
static gdrv_bitmap8 *vscreen, *background_bitmap;
|
||||||
static SDL_Rect DestinationRect;
|
static SDL_Rect DestinationRect;
|
||||||
|
|
||||||
static void init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int height);
|
static void init(gdrv_bitmap8* bmp, int width, int height);
|
||||||
static void uninit();
|
static void uninit();
|
||||||
static void recreate_screen_texture();
|
static void recreate_screen_texture();
|
||||||
static void update();
|
static void update();
|
||||||
static void sprite_modified(render_sprite_type_struct* sprite);
|
static void AddSprite(render_sprite& sprite);
|
||||||
static render_sprite_type_struct* create_sprite(VisualTypes visualType, gdrv_bitmap8* bmp,
|
static void RemoveSprite(render_sprite& sprite);
|
||||||
zmap_header_type* zMap,
|
static void set_background_zmap(zmap_header_type* zMap, int offsetX, int offsetY);
|
||||||
int xPosition, int yPosition, rectangle_type* rect);
|
|
||||||
static void remove_sprite(render_sprite_type_struct* sprite, bool removeFromList);
|
|
||||||
static void remove_ball(render_sprite_type_struct* ball, bool removeFromList);
|
|
||||||
static void sprite_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, zmap_header_type* zMap, int xPos,
|
|
||||||
int yPos);
|
|
||||||
static void sprite_set_bitmap(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp);
|
|
||||||
static void set_background_zmap(struct zmap_header_type* zMap, int offsetX, int offsetY);
|
|
||||||
static void ball_set(render_sprite_type_struct* sprite, gdrv_bitmap8* bmp, float depth, int xPos, int yPos);
|
|
||||||
static void shift(int offsetX, int offsetY);
|
static void shift(int offsetX, int offsetY);
|
||||||
static void build_occlude_list();
|
static void build_occlude_list();
|
||||||
static void SpriteViewer(bool* show);
|
static void SpriteViewer(bool* show);
|
||||||
static void PresentVScreen();
|
static void PresentVScreen();
|
||||||
private:
|
private:
|
||||||
static std::vector<render_sprite_type_struct*> dirty_list, sprite_list, ball_list;
|
static std::vector<render_sprite*> sprite_list, ball_list;
|
||||||
static zmap_header_type* background_zmap;
|
static zmap_header_type* background_zmap;
|
||||||
static int zmap_offset, zmap_offsetY, offset_x, offset_y;
|
static int zmap_offsetX, zmap_offsetY, offset_x, offset_y;
|
||||||
static float zscaler, zmin, zmax;
|
|
||||||
static rectangle_type vscreen_rect;
|
static rectangle_type vscreen_rect;
|
||||||
static gdrv_bitmap8 *ball_bitmap[20];
|
static gdrv_bitmap8 *ball_bitmap[20];
|
||||||
static zmap_header_type* zscreen;
|
static zmap_header_type* zscreen;
|
||||||
|
|
||||||
static void repaint(struct render_sprite_type_struct* sprite);
|
static void repaint(const render_sprite& sprite);
|
||||||
static void paint_balls();
|
static void paint_balls();
|
||||||
static void unpaint_balls();
|
static void unpaint_balls();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue