TBall, nudge v1, ready.

render occlude list.
This commit is contained in:
oz 2020-12-27 18:19:36 +03:00
parent 99fba56a34
commit a143b820af
30 changed files with 494 additions and 328 deletions

Binary file not shown.

View file

@ -1,150 +0,0 @@
#include "pch.h"
#include "DatParser.h"
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
FILE* ff; unsigned char* fdat; int fsiz;
char tbuf[256];
int ngrp;
void err(int n)
{
printf("Error %i\n", n);
exit(n);
}
void cerr(int c, int n)
{
if (c) err(n);
}
void safeprint(char* s, int n)
{
int i;
for (i = 0; i < n; i++)
{
if (!s[i]) break;
fputc(s[i], stdout);
}
}
void printhexbytestr(uchar* s, int n)
{
int i;
for (i = 0; i < n; i++)
printf("%02X", s[i]);
}
void printshortstr(short* s, int n)
{
int i;
for (i = 0; i < n; i++)
printf(" %i", s[i]);
}
void printfloatstr(float* s, int n)
{
int i;
for (i = 0; i < n; i++)
printf(" %f", s[i]);
}
int main2(int argc, const char* argv[])
{
int g, en, es, n, et; unsigned char* p;
printf("pbwdlist - 3D Pinball for Windows DAT file listing program\nby AdrienTD\n\n");
if (argc < 2) { printf("Usage: pbwdlist FILE.DAT\n"); return 1; }
FILE *ff;
fopen_s(&ff,argv[1], "rb");
//ff = fopen(argv[1], "rb");
cerr(!ff, -1);
printf("File: %s\n\n", argv[1]);
fseek(ff, 0, SEEK_END);
fsiz = ftell(ff);
fdat = (unsigned char*)malloc(fsiz);
cerr(!fdat, -2);
fseek(ff, 0, SEEK_SET);
fread(fdat, fsiz, 1, ff);
fclose(ff);
printf("-- Header --");
printf("\nFile signature:\t"); safeprint((char*)fdat, 21);
printf("\nApp name:\t"); safeprint((char*)fdat + 0x15, 50);
printf("\nDescription:\t"); safeprint((char*)fdat + 0x47, 100);
printf("\nFile size:\t%i", *((int*)(fdat + 0xAB)));
printf("\nNum. groups:\t%i", ngrp = *((short*)(fdat + 0xAF)));
printf("\nSize of body:\t%i", *((int*)(fdat + 0xB1)));
printf("\nUnknown value:\t%i", *((short*)(fdat + 0xB5)));
printf("\n\n-- Body --");
p = fdat + 0xB7;
for (g = 0; g < ngrp; g++)
{
n = *(p++);
printf("\nGroup %i:\tnum entries: %i, location: 0x%X\n", g, n, p - fdat - 1);
for (en = 0; en < n; en++)
{
et = *(p++);
if (et)
{
es = *((int*)p); p += 4;
printf("\t\t- type: %i, size: %i\n", et, es);
switch (et)
{
case 1: // Bitmap
printf("\t\t Bitmap, width: %i, height: %i\n", *(ushort*)(p + 1), *(ushort*)(p + 3));
break;
case 3: // Group name
printf("\t\t Group name: ");
safeprint((char*)p, es);
printf("\n"); break;
case 5: // Palette
printf("\t\t Palette\n"); break;
case 9: // String
printf("\t\t String: ");
safeprint((char*)p, es);
printf("\n"); break;
case 10:
//printf("\t\t Content: ");
//printhexbytestr(p, es);
printf("\t\t Shorts:");
printshortstr((short*)p, es / 2);
printf("\n"); break;
case 11:
printf("\t\t Floats:");
printfloatstr((float*)p, es / 4);
printf("\n"); break;
case 12:
printf("\t\t Special bitmap\n"); break;
default:
printf("\t\t Unknown!\n"); break;
}
p += es;
}
else
{
es = *((short*)p); p += 2;
printf("\t\t- type: %i, value: %i\n", et, es);
}
}
}
free(fdat);
return 0;
}
void DatParser::Parse(const char* file)
{
main2(2, new const char* [2] {0, file});
}

View file

@ -1,7 +0,0 @@
#pragma once
class DatParser
{
public:
static void Parse(const char * file);
};

View file

@ -6,7 +6,6 @@
#include <iostream> #include <iostream>
#include "objlist_class.h" #include "objlist_class.h"
#include "partman.h" #include "partman.h"
#include "DatParser.h"
#include "gdrv.h" #include "gdrv.h"
#include "loader.h" #include "loader.h"
#include "pb.h" #include "pb.h"

View file

@ -157,7 +157,6 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="control.h" /> <ClInclude Include="control.h" />
<ClInclude Include="DatParser.h" />
<ClInclude Include="fullscrn.h" /> <ClInclude Include="fullscrn.h" />
<ClInclude Include="gdrv.h" /> <ClInclude Include="gdrv.h" />
<ClInclude Include="high_score.h" /> <ClInclude Include="high_score.h" />
@ -221,7 +220,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="control.cpp" /> <ClCompile Include="control.cpp" />
<ClCompile Include="DatParser.cpp" />
<ClCompile Include="fullscrn.cpp" /> <ClCompile Include="fullscrn.cpp" />
<ClCompile Include="gdrv.cpp" /> <ClCompile Include="gdrv.cpp" />
<ClCompile Include="high_score.cpp" /> <ClCompile Include="high_score.cpp" />

View file

@ -42,9 +42,6 @@
<ClInclude Include="partman.h"> <ClInclude Include="partman.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DatParser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="loader.h"> <ClInclude Include="loader.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -233,9 +230,6 @@
<ClCompile Include="partman.cpp"> <ClCompile Include="partman.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DatParser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="loader.cpp"> <ClCompile Include="loader.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>

View file

@ -1,2 +1,128 @@
#include "pch.h" #include "pch.h"
#include "TBall.h" #include "TBall.h"
#include "loader.h"
#include "maths.h"
#include "objlist_class.h"
#include "proj.h"
#include "render.h"
#include "TPinballTable.h"
#include "TZmapList.h"
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
{
visualStruct visual{};
Unknown9F = 0.0;
Unknown7F = 0.0;
UnknownBaseFlag2 = 1;
Unknown16 = 0;
EdgeCollisionCount = 0;
Unknown8F = 0.0;
Unknown17 = 1;
CollisionFlag = 0;
Speed = 0.0;
Acceleration.Y = 0.0;
Acceleration.X = 0.0;
InvAcceleration.Y = 1000000000.0;
InvAcceleration.X = 1000000000.0;
Position.X = 0.0;
Position.Y = 0.0;
ListBitmap = new TZmapList(0, 4);
auto groupIndex = loader::query_handle("ball");
Offset = *loader::query_float_attribute(groupIndex, 0, 500);
auto visualCount = loader::query_visual_states(groupIndex);
auto index = 0;
if (visualCount > 0)
{
auto visualZPtr = VisualZArray;
do
{
loader::query_visual(groupIndex, index, &visual);
if (ListBitmap)
ListBitmap->Add(visual.Bitmap);
auto visVec = reinterpret_cast<vector_type*>(loader::query_float_attribute(groupIndex, index, 501));
auto zDepth = proj::z_distance(visVec);
++index;
*visualZPtr = zDepth;
++visualZPtr;
}
while (index < visualCount);
}
RenderSprite = render::create_sprite(VisualType::Ball, nullptr, nullptr, 0, 0, nullptr);
PinballTable->CollisionCompOffset = Offset;
Position.Z = Offset;
}
void TBall::Repaint()
{
int pos2D[2];
if (CollisionFlag)
{
Position.Z =
CollisionOffset.X * Position.X +
CollisionOffset.Y * Position.Y +
Offset + CollisionOffset.Z;
}
proj::xform_to_2d(&Position, pos2D);
auto zDepth = proj::z_distance(&Position);
auto zArrPtr = VisualZArray;
int index;
for (index = 0; index < ListBitmap->Count() - 1; ++index, zArrPtr++)
{
if (*zArrPtr <= zDepth) break;
}
auto bmp = static_cast<gdrv_bitmap8*>(ListBitmap->Get(index));
render::ball_set(
RenderSprite,
bmp,
zDepth,
bmp->Width / 2 - pos2D[0],
bmp->Height / 2 - pos2D[1]);
}
void TBall::not_again(TEdgeSegment* edge)
{
if (EdgeCollisionCount < 5)
{
Collisions[EdgeCollisionCount] = edge;
++EdgeCollisionCount;
}
}
bool TBall::already_hit(TEdgeSegment* edge)
{
for (int i = 0; i < EdgeCollisionCount; i++)
{
if (Collisions[i] == edge)
return true;
}
return false;
}
int TBall::Message(int code, float value)
{
if (code == 1024)
{
render::ball_set(RenderSprite, nullptr, 0.0, 0, 0);
Position.X = 0.0;
Unknown16 = 0;
Position.Y = 0.0;
UnknownBaseFlag2 = 0;
CollisionFlag = 0;
Unknown17 = 1;
Acceleration.Y = 0.0;
Position.Z = Offset;
Acceleration.X = 0.0;
Speed = 0.0;
Unknown7F = 0.0;
}
return 0;
}

View file

@ -1,11 +1,35 @@
#pragma once #pragma once
#include "maths.h"
#include "TPinballComponent.h" #include "TPinballComponent.h"
class TBall : class TEdgeSegment;
public TPinballComponent
class TBall : public TPinballComponent
{ {
public : public :
TBall(TPinballTable* table): TPinballComponent(table, -1, false) TBall(TPinballTable* table);
{ void Repaint();
} void not_again(TEdgeSegment* edge);
bool already_hit(TEdgeSegment* edge);
int Message(int code, float value) override;
vector_type Position;
vector_type Acceleration;
float Speed;
float Unknown7F;
float Unknown8F;
float Unknown9F;
vector_type InvAcceleration;
int Unknown13;
int Unknown14;
int Unknown15;
int Unknown16;
int Unknown17;
TEdgeSegment* Collisions[5];
int EdgeCollisionCount;
vector_type CollisionOffset;
int CollisionFlag;
float Offset;
int Unknown29;
float VisualZArray[50];
}; };

View file

@ -8,7 +8,7 @@
TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals) TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals)
{ {
visualStruct visual{}; // [esp+Ch] [ebp-6Ch] visualStruct visual{};
MessageField = 0; MessageField = 0;
UnknownBaseFlag1 = 0; UnknownBaseFlag1 = 0;
@ -18,7 +18,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool
ListBitmap = nullptr; ListBitmap = nullptr;
ListZMap = nullptr; ListZMap = nullptr;
if (table) if (table)
table->ListP1->Add(this); table->ComponentList->Add(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)
@ -80,7 +80,7 @@ TPinballComponent::~TPinballComponent()
{ {
TPinballTable* table = PinballTable; TPinballTable* table = PinballTable;
if (table) if (table)
table->ListP1->Delete(this); table->ComponentList->Delete(this);
delete ListBitmap; delete ListBitmap;
delete ListZMap; delete ListZMap;

View file

@ -7,6 +7,7 @@ class TZmapList;
enum class message_code enum class message_code
{ {
Reset = 1024,
}; };
class TPinballComponent class TPinballComponent

View file

@ -47,8 +47,8 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
{ {
int shortArrLength; int shortArrLength;
ListP1 = new objlist_class(32, 16); ComponentList = new objlist_class(32, 16);
ListP2 = new objlist_class(3, 1); BallList = new objlist_class(3, 1);
CurScoreStruct = nullptr; CurScoreStruct = nullptr;
ScoreBallcount = nullptr; ScoreBallcount = nullptr;
ScorePlayerNumber1 = nullptr; ScorePlayerNumber1 = nullptr;
@ -62,7 +62,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
MultiballFlag = 0; MultiballFlag = 0;
auto ballObj = new TBall(this); auto ballObj = new TBall(this);
ListP2->Add(ballObj); BallList->Add(ballObj);
if (ballObj) if (ballObj)
ballObj->UnknownBaseFlag2 = 0; ballObj->UnknownBaseFlag2 = 0;
new TTableLayer(this); new TTableLayer(this);
@ -188,7 +188,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false)
} }
} }
//build_occlude_list(); render::build_occlude_list();
pinball::InfoTextBox = dynamic_cast<TTextBox*>(find_component("info_text_box")); pinball::InfoTextBox = dynamic_cast<TTextBox*>(find_component("info_text_box"));
pinball::MissTextBox = dynamic_cast<TTextBox*>(find_component("mission_text_box")); pinball::MissTextBox = dynamic_cast<TTextBox*>(find_component("mission_text_box"));
control::make_links(this); control::make_links(this);
@ -212,22 +212,22 @@ TPinballTable::~TPinballTable()
ScoreBallcount = nullptr; ScoreBallcount = nullptr;
} }
delete LightGroup; delete LightGroup;
while (ListP1->Count() > 0) while (ComponentList->Count() > 0)
{ {
delete static_cast<TPinballComponent*>(ListP1->Get(0)); delete static_cast<TPinballComponent*>(ComponentList->Get(0));
} }
delete ListP2; delete BallList;
delete ListP1; delete ComponentList;
} }
TPinballComponent* TPinballTable::find_component(LPCSTR componentName) TPinballComponent* TPinballTable::find_component(LPCSTR componentName)
{ {
int objCount = ListP1->Count(); int objCount = ComponentList->Count();
if (objCount > 0) if (objCount > 0)
{ {
for (int index = 0; index < objCount; ++index) for (int index = 0; index < objCount; ++index)
{ {
TPinballComponent* obj = static_cast<TPinballComponent*>(ListP1->Get(index)); TPinballComponent* obj = static_cast<TPinballComponent*>(ComponentList->Get(index));
const CHAR* groupName = obj->GroupName; const CHAR* groupName = obj->GroupName;
if (groupName && !lstrcmpA(groupName, componentName)) if (groupName && !lstrcmpA(groupName, componentName))
{ {
@ -242,12 +242,12 @@ TPinballComponent* TPinballTable::find_component(LPCSTR componentName)
TPinballComponent* TPinballTable::find_component(int groupIndex) TPinballComponent* TPinballTable::find_component(int groupIndex)
{ {
char Buffer[33]; char Buffer[33];
int objCount = ListP1->Count(); int objCount = ComponentList->Count();
if (objCount > 0) if (objCount > 0)
{ {
for (int index = 0; index < objCount; ++index) for (int index = 0; index < objCount; ++index)
{ {
TPinballComponent* obj = static_cast<TPinballComponent*>(ListP1->Get(index)); TPinballComponent* obj = static_cast<TPinballComponent*>(ComponentList->Get(index));
if (obj->GroupIndex == groupIndex) if (obj->GroupIndex == groupIndex)
return obj; return obj;
} }
@ -305,11 +305,11 @@ void TPinballTable::tilt(float time)
pinball::MissTextBox->Clear(); pinball::MissTextBox->Clear();
pinball::InfoTextBox->Display(pinball::get_rc_string(35, 0), -1.0); pinball::InfoTextBox->Display(pinball::get_rc_string(35, 0), -1.0);
loader::play_sound(this2->SoundIndex3); loader::play_sound(this2->SoundIndex3);
this2->TiltTimeoutTimer = timer::set(30.0, this2, TPinballTable::tilt_timeout); this2->TiltTimeoutTimer = timer::set(30.0, this2, tilt_timeout);
for (int i = 0; i < ListP1->Count(); i++) for (int i = 0; i < ComponentList->Count(); i++)
{ {
static_cast<TPinballComponent*>(ListP1->Get(i))->Message(1011, time); static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1011, time);
} }
this2->LightGroup->Message(8, 0); this2->LightGroup->Message(8, 0);
this2->TiltLockFlag = 1; this2->TiltLockFlag = 1;
@ -320,9 +320,9 @@ void TPinballTable::tilt(float time)
void TPinballTable::port_draw() void TPinballTable::port_draw()
{ {
for (int index = ListP1->Count() - 1; index >= 0; index--) for (int index = ComponentList->Count() - 1; index >= 0; index--)
{ {
static_cast<TPinballComponent*>(ListP1->Get(index))->port_draw(); static_cast<TPinballComponent*>(ComponentList->Get(index))->port_draw();
} }
} }
@ -362,9 +362,9 @@ int TPinballTable::Message(int code, float value)
case 1008: case 1008:
case 1009: case 1009:
case 1010: case 1010:
for (int i = 0; i < ListP1->Count(); i++) for (int i = 0; i < ComponentList->Count(); i++)
{ {
static_cast<TPinballComponent*>(ListP1->Get(i))->Message(code, value); static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(code, value);
} }
break; break;
case 1012: case 1012:
@ -406,10 +406,10 @@ int TPinballTable::Message(int code, float value)
{ {
UnknownP6 = 0; UnknownP6 = 0;
Message(1024, 0.0); Message(1024, 0.0);
/*v8 = (char*)this2->ListP2.ListPtr->Array[0]; auto ball = static_cast<TBall*>(BallList->Get(0));
*(float*)(v8 + 46) = 0.0; ball->Position.Y = 0.0;
*(float*)(v8 + 42) = 0.0; ball->Position.X = 0.0;
*(_DWORD*)(v8 + 50) = -1085485875;*/ ball->Position.Z = -0.8f;
auto playerCount = static_cast<int>(floor(value)); auto playerCount = static_cast<int>(floor(value));
PlayerCount = playerCount; PlayerCount = playerCount;
@ -513,9 +513,9 @@ int TPinballTable::Message(int code, float value)
score::set(ScorePlayerNumber1, nextPlayer + 1); score::set(ScorePlayerNumber1, nextPlayer + 1);
score::update(ScorePlayerNumber1); score::update(ScorePlayerNumber1);
for (int i = 0; i < ListP1->Count(); i++) for (int i = 0; i < ComponentList->Count(); i++)
{ {
static_cast<TPinballComponent*>(ListP1->Get(i))->Message(1020, static_cast<float>(nextPlayer)); static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1020, static_cast<float>(nextPlayer));
} }
char* textboxText = nullptr; char* textboxText = nullptr;
@ -564,9 +564,9 @@ int TPinballTable::Message(int code, float value)
EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout); EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout);
break; break;
case 1024: case 1024:
for (int i = 0; i < ListP1->Count(); i++) for (int i = 0; i < ComponentList->Count(); i++)
{ {
static_cast<TPinballComponent*>(ListP1->Get(i))->Message(1024, 0); static_cast<TPinballComponent*>(ComponentList->Get(i))->Message(1024, 0);
} }
if (ReplayTimer) if (ReplayTimer)
timer::kill(ReplayTimer); timer::kill(ReplayTimer);
@ -608,9 +608,9 @@ void TPinballTable::EndGame_timeout(int timerId, void* caller)
table->EndGameTimeoutTimer = 0; table->EndGameTimeoutTimer = 0;
pb::end_game(); pb::end_game();
for (int i = 0; i < table->ListP1->Count(); i++) for (int i = 0; i < table->ComponentList->Count(); i++)
{ {
static_cast<TPinballComponent*>(table->ListP1->Get(i))->Message(1022, 0); static_cast<TPinballComponent*>(table->ComponentList->Get(i))->Message(1022, 0);
} }
if (table->Demo) if (table->Demo)
table->Demo->Message(1022, 0.0); table->Demo->Message(1022, 0.0);
@ -635,12 +635,6 @@ void TPinballTable::replay_timer_callback(int timerId, void* caller)
void TPinballTable::tilt_timeout(int timerId, void* caller) void TPinballTable::tilt_timeout(int timerId, void* caller)
{ {
auto table = static_cast<TPinballTable*>(caller); auto table = static_cast<TPinballTable*>(caller);
objlist_struct1* v2; // eax
void** v3; // edi
int v4; // ebx
char v5; // [esp+14h] [ebp-Ch]
table->TiltTimeoutTimer = 0; table->TiltTimeoutTimer = 0;
if (table->TiltLockFlag) if (table->TiltLockFlag)
{ {

View file

@ -65,8 +65,8 @@ public:
int YOffset; int YOffset;
int Width; int Width;
int Height; int Height;
objlist_class* ListP1; objlist_class* ComponentList;
objlist_class* ListP2; objlist_class* BallList;
TLightGroup* LightGroup; TLightGroup* LightGroup;
float TableAngleMult; float TableAngleMult;
float TableAngle1; float TableAngle1;

View file

@ -533,7 +533,7 @@ TPinballComponent* control::make_component_link(component_tag* tag)
if (tag->Component) if (tag->Component)
return tag->Component; return tag->Component;
auto compList = TableG->ListP1; auto compList = TableG->ComponentList;
for (int index = 0; index < compList->Count(); index++) for (int index = 0; index < compList->Count(); index++)
{ {
auto comp = static_cast<TPinballComponent*>(compList->Get(index)); auto comp = static_cast<TPinballComponent*>(compList->Get(index));

View file

@ -40,9 +40,10 @@ void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HME
hWnd, hWnd,
(WindowRect1.right - WindowRect1.left - widht2) / 2 - 2, (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2,
WindowRect2.top, WindowRect2.top,
widht2 + 4, widht2 + 4 + 10,
WindowRect2.bottom - WindowRect2.top, WindowRect2.bottom - WindowRect2.top + 10,
0); 0);
// Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480
fullscrn_flag1 = 0; fullscrn_flag1 = 0;
} }
@ -94,8 +95,8 @@ int fullscrn::setWindowFlagsDisDlg()
int fullscrn::enableFullscreen() int fullscrn::enableFullscreen()
{ {
tagRECT Rect{}; // [esp+Ch] [ebp-B0h] tagRECT Rect{};
DEVMODEA DevMode{}; // [esp+1Ch] [ebp-A0h] DEVMODEA DevMode{};
if (ChangeDisplay && !display_changed) if (ChangeDisplay && !display_changed)
{ {
@ -153,7 +154,7 @@ int fullscrn::disableFullscreen()
bool fullscrn::set_menu_mode(int menuEnabled) bool fullscrn::set_menu_mode(int menuEnabled)
{ {
BOOL result; // eax BOOL result;
MenuEnabled = menuEnabled; MenuEnabled = menuEnabled;
GetWindowCenter(); GetWindowCenter();
@ -174,8 +175,8 @@ bool fullscrn::set_menu_mode(int menuEnabled)
void fullscrn::GetWindowCenter() void fullscrn::GetWindowCenter()
{ {
int yPos; // eax int yPos;
tagRECT Rect{}; // [esp+4h] [ebp-10h] tagRECT Rect{};
if (screen_mode) if (screen_mode)
{ {
@ -201,7 +202,7 @@ void fullscrn::force_redraw()
void fullscrn::center_in(HWND parent, HWND child) void fullscrn::center_in(HWND parent, HWND child)
{ {
LONG right; // ebx LONG right;
tagRECT childRect{}, parentRect{}, desktopRect{}; tagRECT childRect{}, parentRect{}, desktopRect{};
GetWindowRect(parent, &parentRect); GetWindowRect(parent, &parentRect);
@ -296,8 +297,8 @@ void fullscrn::activate(int flag)
void fullscrn::fillRect(int right, int bottom) void fullscrn::fillRect(int right, int bottom)
{ {
// Weird reg usage, should be zero // Weird reg usage, should be zero
int v2 = 0; // ebx int v2 = 0;
int v3 = 0; // edi int v3 = 0;
RECT rc; RECT rc;
HGDIOBJ brush = CreateSolidBrush(0); HGDIOBJ brush = CreateSolidBrush(0);

View file

@ -91,7 +91,7 @@ BITMAPINFO* gdrv::DibCreate(__int16 bpp, int width, int height)
void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag) void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag)
{ {
tagPALETTEENTRY pPalEntries[256]; // [esp+4h] [ebp-400h] tagPALETTEENTRY pPalEntries[256];
if (!hpal) if (!hpal)
hpal = static_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE)); hpal = static_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE));
@ -140,7 +140,7 @@ void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag)
int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height) int gdrv::create_bitmap_dib(gdrv_bitmap8* bmp, int width, int height)
{ {
char* bmpBufPtr; // ecx char* bmpBufPtr;
auto dib = DibCreate(8, width, height); auto dib = DibCreate(8, width, height);
DibSetUsage(dib, palette_handle, 1); DibSetUsage(dib, palette_handle, 1);
@ -210,7 +210,6 @@ int gdrv::display_palette(PALETTEENTRY* plt)
{ {
if (plt) if (plt)
{ {
// Todo: verify RGB order
pltDst->peRed = pltSrc->peBlue; pltDst->peRed = pltSrc->peBlue;
pltDst->peGreen = pltSrc->peGreen; pltDst->peGreen = pltSrc->peGreen;
pltDst->peBlue = pltSrc->peRed; pltDst->peBlue = pltSrc->peRed;

View file

@ -415,28 +415,28 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker)
int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual) int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual)
{ {
visualStruct* visual2; // edi visualStruct* visual2;
int groupIndexSum; // eax int groupIndexSum;
int groupIndexSum2; // ebx int groupIndexSum2;
zmap_header_type* bitmap16; // eax zmap_header_type* bitmap16;
__int16* shortArr; // esi __int16* shortArr;
unsigned int shortArrSize; // eax unsigned int shortArrSize;
int index; // ebx int index;
int shortVal; // ecx int shortVal;
__int16* nextShortVal; // esi __int16* nextShortVal;
int nextIndex; // ebx int nextIndex;
int shortValSub100; // ecx int shortValSub100;
int shortValSub300; // ecx int shortValSub300;
int shortValSub304; // ecx int shortValSub304;
int shortValSub602; // ecx int shortValSub602;
int shortValSub1100; // ecx int shortValSub1100;
int shortValSub1101; // ecx int shortValSub1101;
float* floatArr; // eax float* floatArr;
float* nextFloatVal; // esi float* nextFloatVal;
__int64 floatVal; // rax __int64 floatVal;
float* floatArrPtr; // esi float* floatArrPtr;
int groupIndexSum3; // [esp+1Ch] [ebp+8h] int groupIndexSum3;
int shortArrLength; // [esp+24h] [ebp+10h] int shortArrLength;
visual2 = visual; visual2 = visual;
default_vsi(visual); default_vsi(visual);

View file

@ -81,10 +81,10 @@ int maths::rectangle_clip(rectangle_type* rect1, rectangle_type* rect2, rectangl
int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect) int maths::overlapping_box(rectangle_type* rect1, rectangle_type* rect2, rectangle_type* dstRect)
{ {
int v3; // esi int v3;
int v4; // edi int v4;
int v6; // esi int v6;
int v7; // edi int v7;
if (rect1->XPosition >= rect2->XPosition) if (rect1->XPosition >= rect2->XPosition)
{ {
@ -166,9 +166,9 @@ float maths::normalize_2d(vector_type* vec)
void maths::line_init(line_type* line, float x0, float y0, float x1, float y1) void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
{ {
float v9; // st7 float v9;
bool lineDirection; // pf bool lineDirection;
float v11; // eax float v11;
line->Direction.X = x1 - x0; line->Direction.X = x1 - x0;
line->Direction.Y = y1 - y0; line->Direction.Y = y1 - y0;
@ -204,12 +204,12 @@ void maths::line_init(line_type* line, float x0, float y0, float x1, float y1)
float maths::ray_intersect_line(ray_type* ray, line_type* line) float maths::ray_intersect_line(ray_type* ray, line_type* line)
{ {
// Similar to https://rootllama.wordpress.com/2014/06/20/ray-line-segment-intersection-test-in-2d/ // Similar to https://rootllama.wordpress.com/2014/06/20/ray-line-segment-intersection-test-in-2d/
float perpDot; // st7 float perpDot;
float result; // st7 float result;
float v4; // st6 float v4;
bool v5; // c0 bool v5;
bool v6; // c3 bool v6;
float v7; // st6 float v7;
perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X; perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X;
if (perpDot < 0.0) if (perpDot < 0.0)
@ -263,3 +263,9 @@ float maths::magnitude(vector_type* vec)
result = sqrt(magSq); result = sqrt(magSq);
return result; return result;
} }
void maths::vector_add(vector_type* vec1Dst, vector_type* vec2)
{
vec1Dst->X += vec2->X;
vec1Dst->Y += vec2->Y;
}

View file

@ -55,4 +55,5 @@ public:
static float ray_intersect_line(ray_type* ray, line_type* line); static float ray_intersect_line(ray_type* ray, line_type* line);
static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec); static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec);
static float magnitude(vector_type* vec); static float magnitude(vector_type* vec);
static void vector_add(vector_type* vec1Dst, vector_type* vec2);
}; };

View file

@ -1,26 +1,99 @@
#include "pch.h" #include "pch.h"
#include "nudge.h" #include "nudge.h"
void nudge::un_nudge_right(int x, int y)
#include "objlist_class.h"
#include "pb.h"
#include "render.h"
#include "TBall.h"
#include "timer.h"
int nudge::nudged_left;
int nudge::nudged_right;
int nudge::nudged_up;
int nudge::timer;
float nudge::nudge_count;
void nudge::un_nudge_right(int timerId, void* caller)
{ {
if (nudged_right)
_nudge(-2.0, -1.0);
nudged_right = 0;
} }
void nudge::un_nudge_left(int x, int y) void nudge::un_nudge_left(int timerId, void* caller)
{ {
if (nudged_left)
_nudge(2.0, -1.0);
nudged_left = 0;
} }
void nudge::un_nudge_up(int x, int y) void nudge::un_nudge_up(int timerId, void* caller)
{ {
if (nudged_up)
_nudge(0.0, -1.0);
nudged_up = 0;
} }
void nudge::nudge_right() void nudge::nudge_right()
{ {
_nudge(2.0, 1.0);
if (timer)
timer::kill(timer);
timer = timer::set(0.4f, nullptr, un_nudge_right);
nudged_right = 1;
} }
void nudge::nudge_left() void nudge::nudge_left()
{ {
_nudge(-2.0, 1.0);
if (timer)
timer::kill(timer);
timer = timer::set(0.4f, nullptr, un_nudge_left);
nudged_left = 1;
} }
void nudge::nudge_up() void nudge::nudge_up()
{ {
_nudge(0.0, 1.0);
if (timer)
timer::kill(timer);
timer = timer::set(0.4f, nullptr, un_nudge_up);
nudged_up = 1;
}
void nudge::_nudge(float xDiff, float yDiff)
{
vector_type accelMod;
float invAccelX, invAccelY;
auto table = pb::MainTable;
auto ballList = pb::MainTable->BallList;
accelMod.X = xDiff * 0.5f;
accelMod.Y = yDiff * 0.5f;
for (auto index = 0; index < ballList->Count(); index++)
{
auto ball = static_cast<TBall*>(ballList->Get(index));
if (ball->UnknownBaseFlag2 && !ball->Unknown16)
{
ball->Acceleration.X = ball->Acceleration.X * ball->Speed;
ball->Acceleration.Y = ball->Acceleration.Y * ball->Speed;
maths::vector_add(&ball->Acceleration, &accelMod);
ball->Speed = maths::normalize_2d(&ball->Acceleration);
if (0.0 == ball->Acceleration.X)
invAccelX = 1000000000.0;
else
invAccelX = 1.0f / ball->Acceleration.X;
ball->InvAcceleration.X = invAccelX;
if (0.0 == ball->Acceleration.Y)
invAccelY = 1000000000.0;
else
invAccelY = 1.0f / ball->Acceleration.Y;
ball->InvAcceleration.Y = invAccelY;
table = pb::MainTable;
}
}
render::shift(static_cast<int>(floor(xDiff + 0.5)), static_cast<int>(floor(0.5 - yDiff)), 0, 0, table->Width,
table->Height);
} }

View file

@ -1,12 +1,19 @@
#pragma once #pragma once
class nudge class nudge
{ {
public : public:
static void un_nudge_right(int timerId, void* caller);
static void un_nudge_right(int x, int y); static void un_nudge_left(int timerId, void* caller);
static void un_nudge_left(int x, int y); static void un_nudge_up(int timerId, void* caller);
static void un_nudge_up(int x, int y);
static void nudge_right(); static void nudge_right();
static void nudge_left(); static void nudge_left();
static void nudge_up(); static void nudge_up();
static int nudged_left;
static int nudged_right;
static int nudged_up;
static float nudge_count;
private:
static void _nudge(float x, float y);
static int timer;
}; };

View file

@ -88,7 +88,6 @@ int objlist_class::objlist_delete_object(objlist_struct1* ptrToStruct, void* val
if (--index < 0) if (--index < 0)
return 0; return 0;
} }
//ptrToStruct->Array[index] = *(&ptrToStruct->Count + count);
ptrToStruct->Array[index] = ptrToStruct->Array[count - 1]; ptrToStruct->Array[index] = ptrToStruct->Array[count - 1];
--ptrToStruct->Count; --ptrToStruct->Count;
return 1; return 1;

View file

@ -187,7 +187,7 @@ void options::path_free()
int options::get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue) int options::get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue)
{ {
DWORD dwDisposition; // [esp+4h] [ebp-8h] DWORD dwDisposition;
HKEY result = (HKEY)defaultValue, Data = (HKEY)defaultValue; HKEY result = (HKEY)defaultValue, Data = (HKEY)defaultValue;
if (!OptionsRegPath) if (!OptionsRegPath)
@ -205,7 +205,7 @@ int options::get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue)
void options::set_int(LPCSTR optPath, LPCSTR lpValueName, int data) void options::set_int(LPCSTR optPath, LPCSTR lpValueName, int data)
{ {
DWORD dwDisposition; // [esp+4h] [ebp-4h] DWORD dwDisposition;
if (OptionsRegPath) if (OptionsRegPath)
{ {
@ -240,7 +240,7 @@ void options::get_string(LPCSTR optPath, LPCSTR lpValueName, LPSTR lpString1, LP
void options::set_string(LPCSTR optPath, LPCSTR lpValueName, LPCSTR value) void options::set_string(LPCSTR optPath, LPCSTR lpValueName, LPCSTR value)
{ {
DWORD dwDisposition; // [esp+4h] [ebp-4h] DWORD dwDisposition;
if (OptionsRegPath) if (OptionsRegPath)
{ {

View file

@ -77,7 +77,6 @@ struct dat8BitBmpHeader
static_assert(sizeof(dat8BitBmpHeader) == 14, "Wrong size of dat8BitBmpHeader"); static_assert(sizeof(dat8BitBmpHeader) == 14, "Wrong size of dat8BitBmpHeader");
//typedef const char* LPCSTR;
class partman class partman
{ {
public: public:

View file

@ -13,14 +13,15 @@
#include "timer.h" #include "timer.h"
#include "winmain.h" #include "winmain.h"
#include "resource.h" #include "resource.h"
#include "TBall.h"
#include "TDemo.h"
#include "TLightGroup.h" #include "TLightGroup.h"
#include "TPlunger.h" #include "TPlunger.h"
TPinballTable* pb::MainTable = nullptr; TPinballTable* pb::MainTable = nullptr;
datFileStruct* pb::record_table = nullptr; datFileStruct* pb::record_table = nullptr;
int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb:: int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state;
ball_speed_limit, pb::state; float pb::time_now, pb::time_next, pb::ball_speed_limit;
float pb::time_now, pb::time_next;
high_score_struct pb::highscore_table[5]; high_score_struct pb::highscore_table[5];
int pb::init() int pb::init()
@ -63,7 +64,6 @@ int pb::init()
} }
render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]); render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]);
gdrv::fill_bitmap(&render::vscreen, render::vscreen.Width, render::vscreen.Height, 0, 0, '\xFF'); // temp
gdrv::copy_bitmap( gdrv::copy_bitmap(
&render::vscreen, &render::vscreen,
backgroundBmp->Width, backgroundBmp->Width,
@ -89,9 +89,7 @@ int pb::init()
MainTable = new TPinballTable(); MainTable = new TPinballTable();
high_score::read(highscore_table, &state); high_score::read(highscore_table, &state);
//v11 = *(float*)((char*)MainTable->ListP2.ListPtr->Array[0] + 154); ball_speed_limit = static_cast<TBall*>(MainTable->BallList->Get(0))->Offset * 200.0f;
//ball_speed_limit = v11 * 200.0;
--memory::critical_allocation; --memory::critical_allocation;
return 0; return 0;
} }
@ -142,9 +140,8 @@ void pb::mode_change(int mode)
options::menu_check(Menu1_Demo, 1); options::menu_check(Menu1_Demo, 1);
if (MainTable) if (MainTable)
{ {
/*v2 = MainTable->UnknownP48; if (MainTable->Demo)
if (v2) MainTable->Demo->UnknownBaseFlag2 = 1;
*(_BYTE*)(v2 + 5) = 1;*/
} }
} }
else else
@ -154,9 +151,8 @@ void pb::mode_change(int mode)
options::menu_check(Menu1_Demo, 0); options::menu_check(Menu1_Demo, 0);
if (MainTable) if (MainTable)
{ {
/*v1 = MainTable->UnknownP48; if (MainTable->Demo)
if (v1) MainTable->Demo->UnknownBaseFlag2 = 0;
*(_BYTE*)(v1 + 5) = 0;*/
} }
} }
break; break;
@ -208,6 +204,10 @@ void pb::replay_level(int demoMode)
void pb::ballset(int x, int y) void pb::ballset(int x, int y)
{ {
TBall* ball = static_cast<TBall*>(MainTable->BallList->Get(0));
ball->Acceleration.X = x * 30.0f;
ball->Acceleration.Y = y * 30.0f;
ball->Speed = maths::normalize_2d(&ball->Acceleration);
} }
int pb::frame(int time) int pb::frame(int time)
@ -221,30 +221,29 @@ int pb::frame(int time)
//pb::timed_frame(time_now, timeMul, 1); //pb::timed_frame(time_now, timeMul, 1);
time_now = time_next; time_now = time_next;
time_ticks += time; time_ticks += time;
/*if (nudged_left || nudged_right || nudged_up) if (nudge::nudged_left || nudge::nudged_right || nudge::nudged_up)
{ {
nudge_count = timeMul * 4.0 + nudge_count; nudge::nudge_count = timeMul * 4.0f + nudge::nudge_count;
} }
else else
{ {
v2 = nudge_count - timeMul; auto nudgeDec = nudge::nudge_count - timeMul;
if (v2 <= 0.0) if (nudgeDec <= 0.0)
v2 = 0.0; nudgeDec = 0.0;
nudge_count = v2; nudge::nudge_count = nudgeDec;
}*/ }
timer::check(); timer::check();
render::update(); render::update();
//score::update(MainTable->Score1); score::update(MainTable->CurScoreStruct);
/*if (!MainTable->UnknownP83) if (!MainTable->TiltLockFlag)
{ {
if (nudge_count > 0.5) if (nudge::nudge_count > 0.5)
{ {
v3 = pinball:: get_rc_string(25, 0); pinball::InfoTextBox->Display(pinball::get_rc_string(25, 0), 2.0);
pinball::InfoTextBox->Display( v3, 2.0);
} }
if (nudge_count > 1.0) if (nudge::nudge_count > 1.0)
TPinballTable::tilt(MainTable, v1, time_now); MainTable->tilt(time_now);
}*/ }
} }
return 1; return 1;
} }
@ -316,15 +315,15 @@ void pb::keyup(int key)
} }
else if (key == options::Options.LeftTableBumpKey) else if (key == options::Options.LeftTableBumpKey)
{ {
nudge::un_nudge_right(0, 0); nudge::un_nudge_right(0, nullptr);
} }
else if (key == options::Options.RightTableBumpKey) else if (key == options::Options.RightTableBumpKey)
{ {
nudge::un_nudge_left(0, 0); nudge::un_nudge_left(0, nullptr);
} }
else if (key == options::Options.BottomTableBumpKey) else if (key == options::Options.BottomTableBumpKey)
{ {
nudge::un_nudge_up(0, 0); nudge::un_nudge_up(0, nullptr);
} }
} }
} }
@ -379,12 +378,38 @@ void pb::keydown(int key)
switch (key) switch (key)
{ {
case 'B': case 'B':
/**/ TBall* ball;
if (MainTable->BallList->Count() <= 0)
{
ball = new TBall(MainTable);
}
else
{
for (auto index = 0; ;)
{
ball = static_cast<TBall*>(MainTable->BallList->Get(index));
if (!ball->UnknownBaseFlag2)
break;
++index;
if (index >= MainTable->BallList->Count())
{
ball = new TBall(MainTable);
break;
}
}
}
ball->Position.X = 1.0;
ball->UnknownBaseFlag2 = 1;
ball->Position.Z = ball->Offset;
ball->Position.Y = 1.0;
ball->Acceleration.Z = 0.0;
ball->Acceleration.Y = 0.0;
ball->Acceleration.X = 0.0;
break; break;
case 'H': case 'H':
/*auto v1 = get_rc_string(26, 0); char String1[200];
lstrcpyA(&String1, v1); lstrcpyA(String1, pinball::get_rc_string(26, 0));
show_and_set_high_score_dialog(highscore_table, 1000000000, 1, &String1);*/ high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1);
break; break;
case 'M': case 'M':
char buffer[20]; char buffer[20];
@ -450,3 +475,28 @@ void pb::high_scores()
{ {
high_score::show_high_score_dialog(highscore_table); high_score::show_high_score_dialog(highscore_table);
} }
void pb::tilt_no_more()
{
if (MainTable->TiltLockFlag)
pinball::InfoTextBox->Clear();
MainTable->TiltLockFlag = 0;
nudge::nudge_count = -2.0;
}
bool pb::chk_highscore()
{
if (demo_mode)
return false;
int playerIndex = MainTable->PlayerCount - 1;
if (playerIndex < 0)
return false;
for (int i = playerIndex;
high_score::get_score_position(highscore_table, MainTable->PlayerScores[i].ScoreStruct->Score) < 0;
--i)
{
if (--playerIndex < 0)
return false;
}
return true;
}

View file

@ -7,7 +7,7 @@ class pb
{ {
public: public:
static int time_ticks; static int time_ticks;
static int ball_speed_limit; static float ball_speed_limit;
static int cheat_mode, game_mode; static int cheat_mode, game_mode;
static datFileStruct* record_table; static datFileStruct* record_table;
static TPinballTable* MainTable; static TPinballTable* MainTable;
@ -33,6 +33,8 @@ public:
static void launch_ball(); static void launch_ball();
static int end_game(); static int end_game();
static void high_scores(); static void high_scores();
static void tilt_no_more();
static bool chk_highscore();
private : private :
static int demo_mode, mode_countdown_; static int demo_mode, mode_countdown_;
static float time_now, time_next; static float time_now, time_next;

View file

@ -36,9 +36,9 @@ int pinball::get_rc_int(int uID, int* dst)
void pinball::FindShiftKeys() void pinball::FindShiftKeys()
{ {
signed int i; // esi signed int i;
int rightShift; // eax int rightShift;
CHAR stringBuf[20]; // [esp+Ch] [ebp-18h] CHAR stringBuf[20];
RightShift = -1; RightShift = -1;
LeftShift = -1; LeftShift = -1;

View file

@ -6,14 +6,14 @@ float proj::d_, proj::centerx, proj::centery;
void proj::init(float* mat4x3, float d, float centerX, float centerY) void proj::init(float* mat4x3, float d, float centerX, float centerY)
{ {
//for (auto colIndex = 0; colIndex < 4; ++colIndex) /*for (auto colIndex = 0; colIndex < 4; ++colIndex)
//{ {
// // Todo: out of bounds read from mat4x3? // Todo: out of bounds read from mat4x3?
// for (int rowIndex = colIndex, i = 4; i > 0; rowIndex += 4, --i) for (int rowIndex = colIndex, i = 4; i > 0; rowIndex += 4, --i)
// { {
// ((float*)&matrix)[rowIndex] = mat4x3[rowIndex]; ((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;

View file

@ -153,7 +153,7 @@ void render::update()
rect->Width = dirtyRect->Width; rect->Width = dirtyRect->Width;
rect->Height = dirtyRect->Height; rect->Height = dirtyRect->Height;
if (sprite->Unknown6_0 != 0) if (sprite->UnknownFlag != 0)
remove_sprite(sprite); remove_sprite(sprite);
} }
@ -228,7 +228,7 @@ render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bit
sprite->BmpRect.XPosition = xPosition; sprite->BmpRect.XPosition = xPosition;
sprite->Bmp = bmp; sprite->Bmp = bmp;
sprite->VisualType = visualType; sprite->VisualType = visualType;
sprite->Unknown6_0 = 0; sprite->UnknownFlag = 0;
sprite->SpriteArray = nullptr; sprite->SpriteArray = nullptr;
sprite->SpriteCount = 0; sprite->SpriteCount = 0;
if (rect) if (rect)
@ -395,7 +395,7 @@ void render::repaint(struct render_sprite_type_struct* sprite)
for (int index = 0; index < sprite->SpriteCount; index++) for (int index = 0; index < sprite->SpriteCount; index++)
{ {
render_sprite_type_struct* curSprite = sprite->SpriteArray[index]; render_sprite_type_struct* curSprite = sprite->SpriteArray[index];
if (!curSprite->Unknown6_0 && curSprite->Bmp) if (!curSprite->UnknownFlag && curSprite->Bmp)
{ {
if (maths::rectangle_clip(&curSprite->BmpRect, &sprite->DirtyRect, &clipRect)) if (maths::rectangle_clip(&curSprite->BmpRect, &sprite->DirtyRect, &clipRect))
zdrv::paint( zdrv::paint(
@ -523,3 +523,52 @@ void render::shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth,
DestHeight); DestHeight);
unpaint_balls(); unpaint_balls();
} }
void render::build_occlude_list()
{
++memory::critical_allocation;
render_sprite_type_struct** spriteArr = nullptr;
auto spritePtr1 = sprite_list;
for (int index = 0; index < many_sprites; ++index, ++spritePtr1)
{
auto curSprite = *spritePtr1;
if ((*spritePtr1)->SpriteArray)
{
memory::free((*spritePtr1)->SpriteArray);
curSprite->SpriteArray = nullptr;
curSprite->SpriteCount = 0;
}
if (!curSprite->UnknownFlag && curSprite->BoundingRect.Width != -1)
{
if (!spriteArr)
spriteArr = reinterpret_cast<render_sprite_type_struct**>(memory::allocate(0xFA0u));
int occludeCount = 0;
auto spritePtr2 = sprite_list;
for (int i = 0; i < many_sprites; ++i, ++spritePtr2)
{
auto sprite = *spritePtr2;
if (!sprite->UnknownFlag
&& sprite->BoundingRect.Width != -1
&& maths::rectangle_clip(&curSprite->BoundingRect, &sprite->BoundingRect, nullptr)
&& spriteArr)
{
spriteArr[occludeCount++] = sprite;
}
}
if (!curSprite->UnknownFlag && curSprite->Bmp && occludeCount < 2)
occludeCount = 0;
if (occludeCount)
{
curSprite->SpriteArray = reinterpret_cast<render_sprite_type_struct**>(memory::realloc(
spriteArr, 4 * occludeCount));
curSprite->SpriteCount = occludeCount;
spriteArr = nullptr;
}
}
}
if (spriteArr)
memory::free(spriteArr);
--memory::critical_allocation;
}

View file

@ -15,7 +15,7 @@ struct __declspec(align(4)) render_sprite_type_struct
rectangle_type BmpRect; rectangle_type BmpRect;
gdrv_bitmap8* Bmp; gdrv_bitmap8* Bmp;
zmap_header_type* ZMap; zmap_header_type* ZMap;
char Unknown6_0; char UnknownFlag;
VisualType VisualType; VisualType VisualType;
__int16 Depth; __int16 Depth;
rectangle_type BmpRectCopy; rectangle_type BmpRectCopy;
@ -62,4 +62,5 @@ public:
static void paint_balls(); static void paint_balls();
static void unpaint_balls(); static void unpaint_balls();
static void shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth, int DestHeight); static void shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth, int DestHeight);
static void build_occlude_list();
}; };

View file

@ -370,7 +370,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
SetCursor(prevCursor); SetCursor(prevCursor);
auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1); auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1);
auto menuHandle = GetMenu(hWnd); auto menuHandle = GetMenu(hWnd);
fullscrn::init(width, static_cast<int>(height), options::Options.FullScreen, hWnd, menuHandle, fullscrn::init(width, height, options::Options.FullScreen, hWnd, menuHandle,
changeDisplayFg); changeDisplayFg);
--memory::critical_allocation; --memory::critical_allocation;
@ -662,7 +662,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
int winmain::ProcessWindowMessages() int winmain::ProcessWindowMessages()
{ {
MSG Msg{}; // [esp+8h] [ebp-1Ch] MSG Msg{};
if (has_focus && !single_step) if (has_focus && !single_step)
{ {