diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 106d6c1..c18f505 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/DatParser.cpp b/SpaceCadetPinball/DatParser.cpp deleted file mode 100644 index 03dfd3a..0000000 --- a/SpaceCadetPinball/DatParser.cpp +++ /dev/null @@ -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}); -} - - - diff --git a/SpaceCadetPinball/DatParser.h b/SpaceCadetPinball/DatParser.h deleted file mode 100644 index dd99525..0000000 --- a/SpaceCadetPinball/DatParser.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -class DatParser -{ -public: - static void Parse(const char * file); -}; - diff --git a/SpaceCadetPinball/SpaceCadetPinball.cpp b/SpaceCadetPinball/SpaceCadetPinball.cpp index c420c33..1bd6890 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.cpp +++ b/SpaceCadetPinball/SpaceCadetPinball.cpp @@ -6,7 +6,6 @@ #include #include "objlist_class.h" #include "partman.h" -#include "DatParser.h" #include "gdrv.h" #include "loader.h" #include "pb.h" diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj index f6176d6..56c65af 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj @@ -157,7 +157,6 @@ - @@ -221,7 +220,6 @@ - diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters index 88cec46..4088f83 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters @@ -42,9 +42,6 @@ Header Files - - Header Files - Header Files @@ -233,9 +230,6 @@ Source Files - - Source Files - Source Files diff --git a/SpaceCadetPinball/TBall.cpp b/SpaceCadetPinball/TBall.cpp index 356ab02..f866293 100644 --- a/SpaceCadetPinball/TBall.cpp +++ b/SpaceCadetPinball/TBall.cpp @@ -1,2 +1,128 @@ #include "pch.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(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(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; +} diff --git a/SpaceCadetPinball/TBall.h b/SpaceCadetPinball/TBall.h index 190750f..e3ee29e 100644 --- a/SpaceCadetPinball/TBall.h +++ b/SpaceCadetPinball/TBall.h @@ -1,11 +1,35 @@ #pragma once +#include "maths.h" #include "TPinballComponent.h" -class TBall : - public TPinballComponent +class TEdgeSegment; + +class TBall : public TPinballComponent { 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]; }; diff --git a/SpaceCadetPinball/TPinballComponent.cpp b/SpaceCadetPinball/TPinballComponent.cpp index 1d117bc..b0d82cb 100644 --- a/SpaceCadetPinball/TPinballComponent.cpp +++ b/SpaceCadetPinball/TPinballComponent.cpp @@ -8,7 +8,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals) { - visualStruct visual{}; // [esp+Ch] [ebp-6Ch] + visualStruct visual{}; MessageField = 0; UnknownBaseFlag1 = 0; @@ -18,7 +18,7 @@ TPinballComponent::TPinballComponent(TPinballTable* table, int groupIndex, bool ListBitmap = nullptr; ListZMap = nullptr; if (table) - table->ListP1->Add(this); + table->ComponentList->Add(this); if (groupIndex >= 0) GroupName = loader::query_name(groupIndex); if (loadVisuals && groupIndex >= 0) @@ -80,7 +80,7 @@ TPinballComponent::~TPinballComponent() { TPinballTable* table = PinballTable; if (table) - table->ListP1->Delete(this); + table->ComponentList->Delete(this); delete ListBitmap; delete ListZMap; diff --git a/SpaceCadetPinball/TPinballComponent.h b/SpaceCadetPinball/TPinballComponent.h index 0ba7a17..c5db926 100644 --- a/SpaceCadetPinball/TPinballComponent.h +++ b/SpaceCadetPinball/TPinballComponent.h @@ -7,6 +7,7 @@ class TZmapList; enum class message_code { + Reset = 1024, }; class TPinballComponent diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index 871ca27..5efc507 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -47,8 +47,8 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false) { int shortArrLength; - ListP1 = new objlist_class(32, 16); - ListP2 = new objlist_class(3, 1); + ComponentList = new objlist_class(32, 16); + BallList = new objlist_class(3, 1); CurScoreStruct = nullptr; ScoreBallcount = nullptr; ScorePlayerNumber1 = nullptr; @@ -62,7 +62,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false) MultiballFlag = 0; auto ballObj = new TBall(this); - ListP2->Add(ballObj); + BallList->Add(ballObj); if (ballObj) ballObj->UnknownBaseFlag2 = 0; new TTableLayer(this); @@ -188,7 +188,7 @@ TPinballTable::TPinballTable(): TPinballComponent(nullptr, -1, false) } } - //build_occlude_list(); + render::build_occlude_list(); pinball::InfoTextBox = dynamic_cast(find_component("info_text_box")); pinball::MissTextBox = dynamic_cast(find_component("mission_text_box")); control::make_links(this); @@ -212,22 +212,22 @@ TPinballTable::~TPinballTable() ScoreBallcount = nullptr; } delete LightGroup; - while (ListP1->Count() > 0) + while (ComponentList->Count() > 0) { - delete static_cast(ListP1->Get(0)); + delete static_cast(ComponentList->Get(0)); } - delete ListP2; - delete ListP1; + delete BallList; + delete ComponentList; } TPinballComponent* TPinballTable::find_component(LPCSTR componentName) { - int objCount = ListP1->Count(); + int objCount = ComponentList->Count(); if (objCount > 0) { for (int index = 0; index < objCount; ++index) { - TPinballComponent* obj = static_cast(ListP1->Get(index)); + TPinballComponent* obj = static_cast(ComponentList->Get(index)); const CHAR* groupName = obj->GroupName; if (groupName && !lstrcmpA(groupName, componentName)) { @@ -242,12 +242,12 @@ TPinballComponent* TPinballTable::find_component(LPCSTR componentName) TPinballComponent* TPinballTable::find_component(int groupIndex) { char Buffer[33]; - int objCount = ListP1->Count(); + int objCount = ComponentList->Count(); if (objCount > 0) { for (int index = 0; index < objCount; ++index) { - TPinballComponent* obj = static_cast(ListP1->Get(index)); + TPinballComponent* obj = static_cast(ComponentList->Get(index)); if (obj->GroupIndex == groupIndex) return obj; } @@ -305,11 +305,11 @@ void TPinballTable::tilt(float time) pinball::MissTextBox->Clear(); pinball::InfoTextBox->Display(pinball::get_rc_string(35, 0), -1.0); 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(ListP1->Get(i))->Message(1011, time); + static_cast(ComponentList->Get(i))->Message(1011, time); } this2->LightGroup->Message(8, 0); this2->TiltLockFlag = 1; @@ -320,9 +320,9 @@ void TPinballTable::tilt(float time) void TPinballTable::port_draw() { - for (int index = ListP1->Count() - 1; index >= 0; index--) + for (int index = ComponentList->Count() - 1; index >= 0; index--) { - static_cast(ListP1->Get(index))->port_draw(); + static_cast(ComponentList->Get(index))->port_draw(); } } @@ -362,9 +362,9 @@ int TPinballTable::Message(int code, float value) case 1008: case 1009: case 1010: - for (int i = 0; i < ListP1->Count(); i++) + for (int i = 0; i < ComponentList->Count(); i++) { - static_cast(ListP1->Get(i))->Message(code, value); + static_cast(ComponentList->Get(i))->Message(code, value); } break; case 1012: @@ -406,10 +406,10 @@ int TPinballTable::Message(int code, float value) { UnknownP6 = 0; Message(1024, 0.0); - /*v8 = (char*)this2->ListP2.ListPtr->Array[0]; - *(float*)(v8 + 46) = 0.0; - *(float*)(v8 + 42) = 0.0; - *(_DWORD*)(v8 + 50) = -1085485875;*/ + auto ball = static_cast(BallList->Get(0)); + ball->Position.Y = 0.0; + ball->Position.X = 0.0; + ball->Position.Z = -0.8f; auto playerCount = static_cast(floor(value)); PlayerCount = playerCount; @@ -513,9 +513,9 @@ int TPinballTable::Message(int code, float value) score::set(ScorePlayerNumber1, nextPlayer + 1); score::update(ScorePlayerNumber1); - for (int i = 0; i < ListP1->Count(); i++) + for (int i = 0; i < ComponentList->Count(); i++) { - static_cast(ListP1->Get(i))->Message(1020, static_cast(nextPlayer)); + static_cast(ComponentList->Get(i))->Message(1020, static_cast(nextPlayer)); } char* textboxText = nullptr; @@ -564,9 +564,9 @@ int TPinballTable::Message(int code, float value) EndGameTimeoutTimer = timer::set(3.0, this, EndGame_timeout); break; case 1024: - for (int i = 0; i < ListP1->Count(); i++) + for (int i = 0; i < ComponentList->Count(); i++) { - static_cast(ListP1->Get(i))->Message(1024, 0); + static_cast(ComponentList->Get(i))->Message(1024, 0); } if (ReplayTimer) timer::kill(ReplayTimer); @@ -608,9 +608,9 @@ void TPinballTable::EndGame_timeout(int timerId, void* caller) table->EndGameTimeoutTimer = 0; pb::end_game(); - for (int i = 0; i < table->ListP1->Count(); i++) + for (int i = 0; i < table->ComponentList->Count(); i++) { - static_cast(table->ListP1->Get(i))->Message(1022, 0); + static_cast(table->ComponentList->Get(i))->Message(1022, 0); } if (table->Demo) 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) { auto table = static_cast(caller); - - objlist_struct1* v2; // eax - void** v3; // edi - int v4; // ebx - char v5; // [esp+14h] [ebp-Ch] - table->TiltTimeoutTimer = 0; if (table->TiltLockFlag) { diff --git a/SpaceCadetPinball/TPinballTable.h b/SpaceCadetPinball/TPinballTable.h index dd1058a..31dbce7 100644 --- a/SpaceCadetPinball/TPinballTable.h +++ b/SpaceCadetPinball/TPinballTable.h @@ -65,8 +65,8 @@ public: int YOffset; int Width; int Height; - objlist_class* ListP1; - objlist_class* ListP2; + objlist_class* ComponentList; + objlist_class* BallList; TLightGroup* LightGroup; float TableAngleMult; float TableAngle1; diff --git a/SpaceCadetPinball/control.cpp b/SpaceCadetPinball/control.cpp index 1ad2622..5e15d4e 100644 --- a/SpaceCadetPinball/control.cpp +++ b/SpaceCadetPinball/control.cpp @@ -533,7 +533,7 @@ TPinballComponent* control::make_component_link(component_tag* tag) if (tag->Component) return tag->Component; - auto compList = TableG->ListP1; + auto compList = TableG->ComponentList; for (int index = 0; index < compList->Count(); index++) { auto comp = static_cast(compList->Get(index)); diff --git a/SpaceCadetPinball/fullscrn.cpp b/SpaceCadetPinball/fullscrn.cpp index 059ec25..d86940f 100644 --- a/SpaceCadetPinball/fullscrn.cpp +++ b/SpaceCadetPinball/fullscrn.cpp @@ -40,9 +40,10 @@ void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HME hWnd, (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2, WindowRect2.top, - widht2 + 4, - WindowRect2.bottom - WindowRect2.top, + widht2 + 4 + 10, + WindowRect2.bottom - WindowRect2.top + 10, 0); + // Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480 fullscrn_flag1 = 0; } @@ -94,8 +95,8 @@ int fullscrn::setWindowFlagsDisDlg() int fullscrn::enableFullscreen() { - tagRECT Rect{}; // [esp+Ch] [ebp-B0h] - DEVMODEA DevMode{}; // [esp+1Ch] [ebp-A0h] + tagRECT Rect{}; + DEVMODEA DevMode{}; if (ChangeDisplay && !display_changed) { @@ -153,7 +154,7 @@ int fullscrn::disableFullscreen() bool fullscrn::set_menu_mode(int menuEnabled) { - BOOL result; // eax + BOOL result; MenuEnabled = menuEnabled; GetWindowCenter(); @@ -174,8 +175,8 @@ bool fullscrn::set_menu_mode(int menuEnabled) void fullscrn::GetWindowCenter() { - int yPos; // eax - tagRECT Rect{}; // [esp+4h] [ebp-10h] + int yPos; + tagRECT Rect{}; if (screen_mode) { @@ -201,7 +202,7 @@ void fullscrn::force_redraw() void fullscrn::center_in(HWND parent, HWND child) { - LONG right; // ebx + LONG right; tagRECT childRect{}, parentRect{}, desktopRect{}; GetWindowRect(parent, &parentRect); @@ -296,8 +297,8 @@ void fullscrn::activate(int flag) void fullscrn::fillRect(int right, int bottom) { // Weird reg usage, should be zero - int v2 = 0; // ebx - int v3 = 0; // edi + int v2 = 0; + int v3 = 0; RECT rc; HGDIOBJ brush = CreateSolidBrush(0); diff --git a/SpaceCadetPinball/gdrv.cpp b/SpaceCadetPinball/gdrv.cpp index 7173603..c7a62f8 100644 --- a/SpaceCadetPinball/gdrv.cpp +++ b/SpaceCadetPinball/gdrv.cpp @@ -91,7 +91,7 @@ BITMAPINFO* gdrv::DibCreate(__int16 bpp, int width, int height) void gdrv::DibSetUsage(BITMAPINFO* dib, HPALETTE hpal, int someFlag) { - tagPALETTEENTRY pPalEntries[256]; // [esp+4h] [ebp-400h] + tagPALETTEENTRY pPalEntries[256]; if (!hpal) hpal = static_cast(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) { - char* bmpBufPtr; // ecx + char* bmpBufPtr; auto dib = DibCreate(8, width, height); DibSetUsage(dib, palette_handle, 1); @@ -210,7 +210,6 @@ int gdrv::display_palette(PALETTEENTRY* plt) { if (plt) { - // Todo: verify RGB order pltDst->peRed = pltSrc->peBlue; pltDst->peGreen = pltSrc->peGreen; pltDst->peBlue = pltSrc->peRed; diff --git a/SpaceCadetPinball/loader.cpp b/SpaceCadetPinball/loader.cpp index 1fa482b..fe5130a 100644 --- a/SpaceCadetPinball/loader.cpp +++ b/SpaceCadetPinball/loader.cpp @@ -415,28 +415,28 @@ int loader::kicker(int groupIndex, visualKickerStruct* kicker) int loader::query_visual(int groupIndex, int groupIndexOffset, visualStruct* visual) { - visualStruct* visual2; // edi - int groupIndexSum; // eax - int groupIndexSum2; // ebx - zmap_header_type* bitmap16; // eax - __int16* shortArr; // esi - unsigned int shortArrSize; // eax - int index; // ebx - int shortVal; // ecx - __int16* nextShortVal; // esi - int nextIndex; // ebx - int shortValSub100; // ecx - int shortValSub300; // ecx - int shortValSub304; // ecx - int shortValSub602; // ecx - int shortValSub1100; // ecx - int shortValSub1101; // ecx - float* floatArr; // eax - float* nextFloatVal; // esi - __int64 floatVal; // rax - float* floatArrPtr; // esi - int groupIndexSum3; // [esp+1Ch] [ebp+8h] - int shortArrLength; // [esp+24h] [ebp+10h] + visualStruct* visual2; + int groupIndexSum; + int groupIndexSum2; + zmap_header_type* bitmap16; + __int16* shortArr; + unsigned int shortArrSize; + int index; + int shortVal; + __int16* nextShortVal; + int nextIndex; + int shortValSub100; + int shortValSub300; + int shortValSub304; + int shortValSub602; + int shortValSub1100; + int shortValSub1101; + float* floatArr; + float* nextFloatVal; + __int64 floatVal; + float* floatArrPtr; + int groupIndexSum3; + int shortArrLength; visual2 = visual; default_vsi(visual); diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp index cd5f23c..66672ba 100644 --- a/SpaceCadetPinball/maths.cpp +++ b/SpaceCadetPinball/maths.cpp @@ -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 v3; // esi - int v4; // edi - int v6; // esi - int v7; // edi + int v3; + int v4; + int v6; + int v7; 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) { - float v9; // st7 - bool lineDirection; // pf - float v11; // eax + float v9; + bool lineDirection; + float v11; line->Direction.X = x1 - x0; 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) { // Similar to https://rootllama.wordpress.com/2014/06/20/ray-line-segment-intersection-test-in-2d/ - float perpDot; // st7 - float result; // st7 - float v4; // st6 - bool v5; // c0 - bool v6; // c3 - float v7; // st6 + float perpDot; + float result; + float v4; + bool v5; + bool v6; + float v7; perpDot = line->PerpendicularL.Y * ray->Direction.Y + ray->Direction.X * line->PerpendicularL.X; if (perpDot < 0.0) @@ -262,4 +262,10 @@ float maths::magnitude(vector_type* vec) else result = sqrt(magSq); return result; -} \ No newline at end of file +} + +void maths::vector_add(vector_type* vec1Dst, vector_type* vec2) +{ + vec1Dst->X += vec2->X; + vec1Dst->Y += vec2->Y; +} diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h index b433246..b0b9b4c 100644 --- a/SpaceCadetPinball/maths.h +++ b/SpaceCadetPinball/maths.h @@ -18,7 +18,7 @@ struct __declspec(align(4)) rectangle_type struct circle_type { - vector_type Center; + vector_type Center; float RadiusSq; }; @@ -55,4 +55,5 @@ public: static float ray_intersect_line(ray_type* ray, line_type* line); static void cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec); static float magnitude(vector_type* vec); + static void vector_add(vector_type* vec1Dst, vector_type* vec2); }; diff --git a/SpaceCadetPinball/nudge.cpp b/SpaceCadetPinball/nudge.cpp index 410202c..6d9e3b1 100644 --- a/SpaceCadetPinball/nudge.cpp +++ b/SpaceCadetPinball/nudge.cpp @@ -1,26 +1,99 @@ #include "pch.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() { + _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() { + _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() { + _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(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(floor(xDiff + 0.5)), static_cast(floor(0.5 - yDiff)), 0, 0, table->Width, + table->Height); } diff --git a/SpaceCadetPinball/nudge.h b/SpaceCadetPinball/nudge.h index 7301902..fb4ca9e 100644 --- a/SpaceCadetPinball/nudge.h +++ b/SpaceCadetPinball/nudge.h @@ -1,12 +1,19 @@ #pragma once class nudge { -public : - - static void un_nudge_right(int x, int y); - static void un_nudge_left(int x, int y); - static void un_nudge_up(int x, int y); +public: + static void un_nudge_right(int timerId, void* caller); + static void un_nudge_left(int timerId, void* caller); + static void un_nudge_up(int timerId, void* caller); static void nudge_right(); static void nudge_left(); 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; }; diff --git a/SpaceCadetPinball/objlist_class.cpp b/SpaceCadetPinball/objlist_class.cpp index 8a4a2b4..af319d3 100644 --- a/SpaceCadetPinball/objlist_class.cpp +++ b/SpaceCadetPinball/objlist_class.cpp @@ -88,7 +88,6 @@ int objlist_class::objlist_delete_object(objlist_struct1* ptrToStruct, void* val if (--index < 0) return 0; } - //ptrToStruct->Array[index] = *(&ptrToStruct->Count + count); ptrToStruct->Array[index] = ptrToStruct->Array[count - 1]; --ptrToStruct->Count; return 1; diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index 27bf97e..1fbec02 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -187,7 +187,7 @@ void options::path_free() 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; 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) { - DWORD dwDisposition; // [esp+4h] [ebp-4h] + DWORD dwDisposition; 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) { - DWORD dwDisposition; // [esp+4h] [ebp-4h] + DWORD dwDisposition; if (OptionsRegPath) { diff --git a/SpaceCadetPinball/partman.h b/SpaceCadetPinball/partman.h index 77a7ac0..d5f478a 100644 --- a/SpaceCadetPinball/partman.h +++ b/SpaceCadetPinball/partman.h @@ -77,7 +77,6 @@ struct dat8BitBmpHeader static_assert(sizeof(dat8BitBmpHeader) == 14, "Wrong size of dat8BitBmpHeader"); -//typedef const char* LPCSTR; class partman { public: diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index 0105472..d6a33cb 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -13,14 +13,15 @@ #include "timer.h" #include "winmain.h" #include "resource.h" +#include "TBall.h" +#include "TDemo.h" #include "TLightGroup.h" #include "TPlunger.h" TPinballTable* pb::MainTable = 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:: - ball_speed_limit, pb::state; -float pb::time_now, pb::time_next; +int pb::time_ticks = 0, pb::demo_mode = 0, pb::cheat_mode = 0, pb::game_mode = 2, pb::mode_countdown_, pb::state; +float pb::time_now, pb::time_next, pb::ball_speed_limit; high_score_struct pb::highscore_table[5]; int pb::init() @@ -63,7 +64,6 @@ int pb::init() } 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( &render::vscreen, backgroundBmp->Width, @@ -89,9 +89,7 @@ int pb::init() MainTable = new TPinballTable(); high_score::read(highscore_table, &state); - //v11 = *(float*)((char*)MainTable->ListP2.ListPtr->Array[0] + 154); - //ball_speed_limit = v11 * 200.0; - + ball_speed_limit = static_cast(MainTable->BallList->Get(0))->Offset * 200.0f; --memory::critical_allocation; return 0; } @@ -142,9 +140,8 @@ void pb::mode_change(int mode) options::menu_check(Menu1_Demo, 1); if (MainTable) { - /*v2 = MainTable->UnknownP48; - if (v2) - *(_BYTE*)(v2 + 5) = 1;*/ + if (MainTable->Demo) + MainTable->Demo->UnknownBaseFlag2 = 1; } } else @@ -154,9 +151,8 @@ void pb::mode_change(int mode) options::menu_check(Menu1_Demo, 0); if (MainTable) { - /*v1 = MainTable->UnknownP48; - if (v1) - *(_BYTE*)(v1 + 5) = 0;*/ + if (MainTable->Demo) + MainTable->Demo->UnknownBaseFlag2 = 0; } } break; @@ -208,6 +204,10 @@ void pb::replay_level(int demoMode) void pb::ballset(int x, int y) { + TBall* ball = static_cast(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) @@ -221,30 +221,29 @@ int pb::frame(int time) //pb::timed_frame(time_now, timeMul, 1); time_now = time_next; 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 { - v2 = nudge_count - timeMul; - if (v2 <= 0.0) - v2 = 0.0; - nudge_count = v2; - }*/ + auto nudgeDec = nudge::nudge_count - timeMul; + if (nudgeDec <= 0.0) + nudgeDec = 0.0; + nudge::nudge_count = nudgeDec; + } timer::check(); render::update(); - //score::update(MainTable->Score1); - /*if (!MainTable->UnknownP83) + score::update(MainTable->CurScoreStruct); + if (!MainTable->TiltLockFlag) { - if (nudge_count > 0.5) + if (nudge::nudge_count > 0.5) { - v3 = pinball:: get_rc_string(25, 0); - pinball::InfoTextBox->Display( v3, 2.0); + pinball::InfoTextBox->Display(pinball::get_rc_string(25, 0), 2.0); } - if (nudge_count > 1.0) - TPinballTable::tilt(MainTable, v1, time_now); - }*/ + if (nudge::nudge_count > 1.0) + MainTable->tilt(time_now); + } } return 1; } @@ -316,15 +315,15 @@ void pb::keyup(int key) } else if (key == options::Options.LeftTableBumpKey) { - nudge::un_nudge_right(0, 0); + nudge::un_nudge_right(0, nullptr); } else if (key == options::Options.RightTableBumpKey) { - nudge::un_nudge_left(0, 0); + nudge::un_nudge_left(0, nullptr); } 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) { case 'B': - /**/ + TBall* ball; + if (MainTable->BallList->Count() <= 0) + { + ball = new TBall(MainTable); + } + else + { + for (auto index = 0; ;) + { + ball = static_cast(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; case 'H': - /*auto v1 = get_rc_string(26, 0); - lstrcpyA(&String1, v1); - show_and_set_high_score_dialog(highscore_table, 1000000000, 1, &String1);*/ + char String1[200]; + lstrcpyA(String1, pinball::get_rc_string(26, 0)); + high_score::show_and_set_high_score_dialog(highscore_table, 1000000000, 1, String1); break; case 'M': char buffer[20]; @@ -450,3 +475,28 @@ void pb::high_scores() { 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; +} diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index e2fe988..7eb730e 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -7,7 +7,7 @@ class pb { public: static int time_ticks; - static int ball_speed_limit; + static float ball_speed_limit; static int cheat_mode, game_mode; static datFileStruct* record_table; static TPinballTable* MainTable; @@ -33,6 +33,8 @@ public: static void launch_ball(); static int end_game(); static void high_scores(); + static void tilt_no_more(); + static bool chk_highscore(); private : static int demo_mode, mode_countdown_; static float time_now, time_next; diff --git a/SpaceCadetPinball/pinball.cpp b/SpaceCadetPinball/pinball.cpp index 92cf9e3..3fc4855 100644 --- a/SpaceCadetPinball/pinball.cpp +++ b/SpaceCadetPinball/pinball.cpp @@ -36,9 +36,9 @@ int pinball::get_rc_int(int uID, int* dst) void pinball::FindShiftKeys() { - signed int i; // esi - int rightShift; // eax - CHAR stringBuf[20]; // [esp+Ch] [ebp-18h] + signed int i; + int rightShift; + CHAR stringBuf[20]; RightShift = -1; LeftShift = -1; diff --git a/SpaceCadetPinball/proj.cpp b/SpaceCadetPinball/proj.cpp index 9bd33d6..dcefda9 100644 --- a/SpaceCadetPinball/proj.cpp +++ b/SpaceCadetPinball/proj.cpp @@ -6,14 +6,14 @@ float proj::d_, proj::centerx, proj::centery; void proj::init(float* mat4x3, float d, float centerX, float centerY) { - //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]; - // } - //} + /*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); matrix.Row3.X = 0.0; diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp index 3e098ff..97a3713 100644 --- a/SpaceCadetPinball/render.cpp +++ b/SpaceCadetPinball/render.cpp @@ -153,7 +153,7 @@ void render::update() rect->Width = dirtyRect->Width; rect->Height = dirtyRect->Height; - if (sprite->Unknown6_0 != 0) + if (sprite->UnknownFlag != 0) remove_sprite(sprite); } @@ -228,7 +228,7 @@ render_sprite_type_struct* render::create_sprite(VisualType visualType, gdrv_bit sprite->BmpRect.XPosition = xPosition; sprite->Bmp = bmp; sprite->VisualType = visualType; - sprite->Unknown6_0 = 0; + sprite->UnknownFlag = 0; sprite->SpriteArray = nullptr; sprite->SpriteCount = 0; if (rect) @@ -395,7 +395,7 @@ void render::repaint(struct render_sprite_type_struct* sprite) for (int index = 0; index < sprite->SpriteCount; 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)) zdrv::paint( @@ -523,3 +523,52 @@ void render::shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth, DestHeight); 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(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(memory::realloc( + spriteArr, 4 * occludeCount)); + curSprite->SpriteCount = occludeCount; + spriteArr = nullptr; + } + } + } + + if (spriteArr) + memory::free(spriteArr); + + --memory::critical_allocation; +} diff --git a/SpaceCadetPinball/render.h b/SpaceCadetPinball/render.h index b6a4fd3..b6427c3 100644 --- a/SpaceCadetPinball/render.h +++ b/SpaceCadetPinball/render.h @@ -15,7 +15,7 @@ struct __declspec(align(4)) render_sprite_type_struct rectangle_type BmpRect; gdrv_bitmap8* Bmp; zmap_header_type* ZMap; - char Unknown6_0; + char UnknownFlag; VisualType VisualType; __int16 Depth; rectangle_type BmpRectCopy; @@ -62,4 +62,5 @@ public: static void paint_balls(); static void unpaint_balls(); static void shift(int offsetX, int offsetY, int xSrc, int ySrc, int DestWidth, int DestHeight); + static void build_occlude_list(); }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 4355eda..eb4c27c 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -370,7 +370,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP SetCursor(prevCursor); auto changeDisplayFg = options::get_int(nullptr, "Change Display", 1); auto menuHandle = GetMenu(hWnd); - fullscrn::init(width, static_cast(height), options::Options.FullScreen, hWnd, menuHandle, + fullscrn::init(width, height, options::Options.FullScreen, hWnd, menuHandle, changeDisplayFg); --memory::critical_allocation; @@ -662,7 +662,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP int winmain::ProcessWindowMessages() { - MSG Msg{}; // [esp+8h] [ebp-1Ch] + MSG Msg{}; if (has_focus && !single_step) {