diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx
index a4ce67b..8031207 100644
Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ
diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp
index 115418e..9c4df2e 100644
--- a/SpaceCadetPinball/Sound.cpp
+++ b/SpaceCadetPinball/Sound.cpp
@@ -8,3 +8,7 @@ void Sound::Enable(int a1, int a2, int a3)
void Sound::nullsub_1(int a1, int a2, int a3)
{
}
+
+void Sound::Idle()
+{
+}
diff --git a/SpaceCadetPinball/Sound.h b/SpaceCadetPinball/Sound.h
index a7f123f..1fca981 100644
--- a/SpaceCadetPinball/Sound.h
+++ b/SpaceCadetPinball/Sound.h
@@ -3,5 +3,6 @@ class Sound
{
public:
static void Enable(int a1, int a2, int a3);
- static void nullsub_1(int a1, int a2, int a3);
+ static void nullsub_1(int a1, int a2, int a3);
+ static void Idle();
};
diff --git a/SpaceCadetPinball/SpaceCadetPinball.cpp b/SpaceCadetPinball/SpaceCadetPinball.cpp
index 6654938..92292a6 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.cpp
+++ b/SpaceCadetPinball/SpaceCadetPinball.cpp
@@ -9,6 +9,7 @@
#include "DatParser.h"
#include "gdrv.h"
#include "loader.h"
+#include "pb.h"
#include "pinball.h"
#include "score.h"
#include "TPinballTable.h"
@@ -17,17 +18,19 @@
int main()
{
std::cout << "Hello World!\n";
-
- pinball::hinst = GetModuleHandleA(nullptr);
- char cmdLine[1]{};
- //WinMain(pinball::hinst, 0, cmdLine, 10);
+ {
+ // Testing with UI
+ /* lstrcpyA(pinball::DatFileName, "PINBALL.DAT");
+ pinball::hinst = GetModuleHandleA(nullptr);
+ char cmdLine[1]{};
+ pb::init();
+ WinMain(pinball::hinst, 0, cmdLine, 10);*/
+ }
gdrv::init(0, 0);
auto dib = gdrv::DibCreate(8, 1, 1);
gdrv::DibSetUsage(dib, 0, 1);
- render::init(0, 1, 2, 800, 600);
-
objlist_class d = objlist_class(2, 4);
for (int i = 0; i < 100; i++)
{
@@ -37,10 +40,9 @@ int main()
auto xx = sizeof(datFileHeader);
- char dataFileName[300];
- partman::make_path_name(dataFileName, "PINBALL.DAT");
- auto datFile = partman::load_records(dataFileName);
- assert(datFile);
+ lstrcpyA(pinball::DatFileName, "PINBALL.DAT");
+ pb::init();
+ auto datFile = pb::record_table;
assert(partman::field_size_nth(datFile, 0, datFieldTypes::String, 0) == 43);
assert(partman::field_size_nth(datFile, 2, datFieldTypes::Palette, 0) == 1024);
@@ -55,7 +57,6 @@ int main()
assert(memcmp(partman::field_labeled(datFile, "table_size", datFieldTypes::ShortArray), new short[2]{ 600, 416 }, 2 * 2) == 0);
//loader::error(25, 26);
- loader::loadfrom(datFile);
loader::get_sound_id(18);
visualStruct visual1{};
loader::material(96, &visual1);
@@ -65,7 +66,7 @@ int main()
auto score1 = score::create("score1", nullptr);
- auto pinballTable = new TPinballTable();
+ auto pinballTable = pb::MainTable;
//pinballTable->find_component(1);
for (int i = 0; i < 190; i++)
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
index fbbd5a2..5350bc3 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
@@ -165,6 +165,7 @@
+
@@ -182,6 +183,7 @@
+
@@ -226,6 +228,7 @@
Create
+
@@ -243,6 +246,7 @@
+
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
index 52e0826..56254e7 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
@@ -195,6 +195,12 @@
Header Files\TCollisionComponent
+
+ Header Files
+
+
+ Header Files
+
@@ -356,6 +362,12 @@
Source Files\TCollisionComponent
+
+ Source Files
+
+
+ Source Files
+
diff --git a/SpaceCadetPinball/TCollisionComponent.cpp b/SpaceCadetPinball/TCollisionComponent.cpp
index 1dc273e..5da51ae 100644
--- a/SpaceCadetPinball/TCollisionComponent.cpp
+++ b/SpaceCadetPinball/TCollisionComponent.cpp
@@ -48,3 +48,12 @@ TCollisionComponent::~TCollisionComponent()
}
delete this->EdgeList;
}
+
+
+void TCollisionComponent::port_draw()
+{
+ for (int index = EdgeList->Count() - 1; index >= 0; index--)
+ {
+ static_cast(EdgeList->Get(index))->port_draw();
+ }
+}
diff --git a/SpaceCadetPinball/TCollisionComponent.h b/SpaceCadetPinball/TCollisionComponent.h
index b31b30d..738c49f 100644
--- a/SpaceCadetPinball/TCollisionComponent.h
+++ b/SpaceCadetPinball/TCollisionComponent.h
@@ -17,4 +17,5 @@ public:
TCollisionComponent(TPinballTable* table, int groupIndex, bool createWall);
~TCollisionComponent();
+ void port_draw() override;
};
diff --git a/SpaceCadetPinball/TEdgeSegment.cpp b/SpaceCadetPinball/TEdgeSegment.cpp
index 8669db5..95235b7 100644
--- a/SpaceCadetPinball/TEdgeSegment.cpp
+++ b/SpaceCadetPinball/TEdgeSegment.cpp
@@ -11,6 +11,10 @@ TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsign
this->Unknown3_0 = 0;
}
+void TEdgeSegment::port_draw()
+{
+}
+
TEdgeSegment* TEdgeSegment::install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
unsigned int visual_flag,
float offset, int someValue)
diff --git a/SpaceCadetPinball/TEdgeSegment.h b/SpaceCadetPinball/TEdgeSegment.h
index e652f7c..286a218 100644
--- a/SpaceCadetPinball/TEdgeSegment.h
+++ b/SpaceCadetPinball/TEdgeSegment.h
@@ -19,14 +19,13 @@ public:
int VisualFlag;
TEdgeSegment(TCollisionComponent* collComp, char* someFlag, unsigned int visualFlag);
+ virtual ~TEdgeSegment() = default;
- virtual ~TEdgeSegment()
- {
- }
-
+ virtual void EdgeCollision(TBall* ball, float coef) = 0;
+ virtual void port_draw();
virtual void place_in_grid() = 0;
virtual double FindCollisionDistance(ray_type* ray) = 0;
- virtual void EdgeCollision(TBall* ball, float coef) = 0;
+
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* flagPtr,
unsigned int visual_flag, float offset, int someValue);
};
diff --git a/SpaceCadetPinball/TPinballComponent.cpp b/SpaceCadetPinball/TPinballComponent.cpp
index 26447d9..982e5d9 100644
--- a/SpaceCadetPinball/TPinballComponent.cpp
+++ b/SpaceCadetPinball/TPinballComponent.cpp
@@ -95,6 +95,10 @@ int TPinballComponent::Message(int message1, float message2)
return 0;
}
+void TPinballComponent::port_draw()
+{
+}
+
void TPinballComponent::put_scoring(int score1, int score2)
{
}
diff --git a/SpaceCadetPinball/TPinballComponent.h b/SpaceCadetPinball/TPinballComponent.h
index 5a26850..3bdc99f 100644
--- a/SpaceCadetPinball/TPinballComponent.h
+++ b/SpaceCadetPinball/TPinballComponent.h
@@ -10,6 +10,7 @@ public:
TPinballComponent(TPinballTable* table, int groupIndex, bool loadVisuals);
virtual ~TPinballComponent();
virtual int Message(int message1, float message2);
+ virtual void port_draw();
virtual void put_scoring(int score1, int score2);
virtual int get_scoring(int score1);
diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp
index c64ebf2..a12da8b 100644
--- a/SpaceCadetPinball/TPinballTable.cpp
+++ b/SpaceCadetPinball/TPinballTable.cpp
@@ -262,3 +262,12 @@ TPinballComponent* TPinballTable::find_component(int groupIndex)
MessageBoxA(nullptr, "Table cant find (lh):", Buffer, 0x2000u);
return nullptr;
}
+
+
+void TPinballTable::port_draw()
+{
+ for (int index = ListP1->Count() - 1; index >= 0; index--)
+ {
+ static_cast(ListP1->Get(index))->port_draw();
+ }
+}
\ No newline at end of file
diff --git a/SpaceCadetPinball/TPinballTable.h b/SpaceCadetPinball/TPinballTable.h
index 2b648b1..e78d0ad 100644
--- a/SpaceCadetPinball/TPinballTable.h
+++ b/SpaceCadetPinball/TPinballTable.h
@@ -14,6 +14,7 @@ public:
~TPinballTable();
TPinballComponent* find_component(LPCSTR componentName);
TPinballComponent* find_component(int groupIndex);
+ void port_draw() override;
TFlipper* FlipperL;
TFlipper* FlipperR;
diff --git a/SpaceCadetPinball/TTextBox.cpp b/SpaceCadetPinball/TTextBox.cpp
index 4f9984b..6eb2a78 100644
--- a/SpaceCadetPinball/TTextBox.cpp
+++ b/SpaceCadetPinball/TTextBox.cpp
@@ -5,4 +5,12 @@
int TTextBox::Message(int a2, float a3)
{
return 0;
-}
\ No newline at end of file
+}
+
+void TTextBox::Clear()
+{
+}
+
+void TTextBox::Display(char* text, float time)
+{
+}
diff --git a/SpaceCadetPinball/TTextBox.h b/SpaceCadetPinball/TTextBox.h
index bf27bcd..bd85f56 100644
--- a/SpaceCadetPinball/TTextBox.h
+++ b/SpaceCadetPinball/TTextBox.h
@@ -10,4 +10,6 @@ public:
}
int Message(int a2, float a3) override;
+ void Clear();
+ void Display(char* text, float time);
};
diff --git a/SpaceCadetPinball/maths.cpp b/SpaceCadetPinball/maths.cpp
index a0b78b1..cd5f23c 100644
--- a/SpaceCadetPinball/maths.cpp
+++ b/SpaceCadetPinball/maths.cpp
@@ -252,3 +252,14 @@ void maths::cross(vector_type* vec1, vector_type* vec2, vector_type* dstVec)
dstVec->Y = vec2->X * vec1->Z - vec1->X * vec2->Z;
dstVec->Z = vec1->X * vec2->Y - vec2->X * vec1->Y;
}
+
+float maths::magnitude(vector_type* vec)
+{
+ float result;
+ auto magSq = vec->X * vec->X + vec->Y * vec->Y + vec->Z * vec->Z;
+ if (magSq == 0.0)
+ result = 0.0;
+ else
+ result = sqrt(magSq);
+ return result;
+}
\ No newline at end of file
diff --git a/SpaceCadetPinball/maths.h b/SpaceCadetPinball/maths.h
index 74f6d57..b433246 100644
--- a/SpaceCadetPinball/maths.h
+++ b/SpaceCadetPinball/maths.h
@@ -54,4 +54,5 @@ public:
static void line_init(line_type* line, float x0, float y0, float x1, float y1);
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);
};
diff --git a/SpaceCadetPinball/partman.cpp b/SpaceCadetPinball/partman.cpp
index 1d77b4c..0070842 100644
--- a/SpaceCadetPinball/partman.cpp
+++ b/SpaceCadetPinball/partman.cpp
@@ -99,7 +99,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
{
auto entryType = static_cast(_lread_char(fileHandle));
entryData->EntryType = entryType;
- int fieldSize = _field_size[(int)entryType];
+ int fieldSize = _field_size[static_cast(entryType)];
if (fieldSize < 0)
{
fieldSize = _lread_long(fileHandle);
@@ -165,8 +165,8 @@ void partman::unload_records(datFileStruct* datFile)
{
if (entry->Buffer)
{
- //if (HIWORD(entry->EntryType) == 1)
- //gdrv_destroy_bitmap(entry->Buffer);
+ if (entry->EntryType == datFieldTypes::Bitmap8bit)
+ gdrv::destroy_bitmap((gdrv_bitmap8*)entry->Buffer);
memory::free(entry->Buffer);
}
++entryIndex;
@@ -323,30 +323,6 @@ char* partman::field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTy
return result;
}
-
-int partman::make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize)
-{
- int nameSize = GetModuleFileNameA(nullptr, lpFilename, nSize);
- if (!nameSize || nameSize == nSize)
- return 1;
- for (CHAR* i = &lpFilename[nameSize]; i > lpFilename; --i)
- {
- if (*i == '\\' || *i == ':')
- {
- i[1] = 0;
- break;
- }
- --nameSize;
- }
- if (nameSize + 13 < nSize)
- {
- lstrcatA(lpFilename, lpString2);
- return 0;
- }
- lstrcatA(lpFilename, "?");
- return 1;
-}
-
char partman::_lread_char(HFILE hFile)
{
char Buffer = 0;
diff --git a/SpaceCadetPinball/partman.h b/SpaceCadetPinball/partman.h
index f54c573..77a7ac0 100644
--- a/SpaceCadetPinball/partman.h
+++ b/SpaceCadetPinball/partman.h
@@ -89,9 +89,6 @@ public:
static int field_size(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType);
static int record_labeled(datFileStruct* datFile, LPCSTR targetGroupName);
static char* field_labeled(datFileStruct* datFile, LPCSTR lpString, datFieldTypes fieldType);
-
- static int make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize = 0x12Cu);
-
private:
static short _field_size[];
static char _lread_char(HFILE hFile);
diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp
index 298b92e..a566fef 100644
--- a/SpaceCadetPinball/pb.cpp
+++ b/SpaceCadetPinball/pb.cpp
@@ -1,8 +1,89 @@
#include "pch.h"
#include "pb.h"
+
+#include "memory.h"
+#include "pinball.h"
+#include "proj.h"
#include "render.h"
+#include "loader.h"
+#include "options.h"
+#include "timer.h"
TPinballTable* pb::MainTable = nullptr;
+datFileStruct* pb::record_table = nullptr;
+int pb::time_ticks = 0, pb::demo_mode = 0;
+
+int pb::init()
+{
+ float projMat[12], zMin = 0, zScaler = 0;
+ CHAR datFileName[300];
+ CHAR dataFilePath[300];
+
+ ++memory::critical_allocation;
+ lstrcpyA(datFileName, pinball::DatFileName);
+ pinball::make_path_name(dataFilePath, datFileName, 300);
+ record_table = partman::load_records(dataFilePath);
+
+ auto useBmpFont = 0;
+ pinball::get_rc_int(158, &useBmpFont);
+ if (useBmpFont)
+ score::load_msg_font("pbmsg_ft");
+
+ if (!record_table)
+ return (int)&record_table->NumberOfGroups + 1;
+
+ auto plt = (PALETTEENTRY*)partman::field_labeled(record_table, "background", datFieldTypes::Palette);
+ gdrv::display_palette(plt);
+
+ auto tableSize = (__int16*)partman::field_labeled(record_table, "table_size", datFieldTypes::ShortArray);
+ auto backgroundBmp = (gdrv_bitmap8*)partman::field_labeled(record_table, "background", datFieldTypes::Bitmap8bit);
+ auto cameraInfo = (float*)partman::field_labeled(record_table, "camera_info", datFieldTypes::FloatArray);
+
+ if (cameraInfo)
+ {
+ memcpy(&projMat, cameraInfo, sizeof(float) * 4 * 3);
+ cameraInfo += 12;
+
+ auto projCenterX = tableSize[0] * 0.5f;
+ auto projCenterY = tableSize[1] * 0.5f;
+ auto projD = cameraInfo[0];
+ proj::init(projMat, projD, projCenterX, projCenterY);
+ zMin = cameraInfo[1];
+ zScaler = cameraInfo[2];
+ }
+
+ render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]);
+ gdrv::copy_bitmap(
+ &render::vscreen,
+ backgroundBmp->Width,
+ backgroundBmp->Height,
+ backgroundBmp->XPosition,
+ backgroundBmp->YPosition,
+ backgroundBmp,
+ 0,
+ 0);
+
+ gdrv::destroy_bitmap(backgroundBmp);
+ loader::loadfrom(record_table);
+
+ if (pinball::quickFlag)
+ mode_change(1);
+ else
+ mode_change(3);
+
+ time_ticks = 0;
+ timer::init(150);
+ score::init();
+
+ MainTable = new TPinballTable();
+
+ //high_score_read(highscore_table, (int)&pb_state);
+ //v11 = *(float*)((char*)MainTable->ListP2.ListPtr->Array[0] + 154);
+ //ball_speed_limit = v11 * 200.0;
+
+ --memory::critical_allocation;
+ return 0;
+}
void pb::reset_table()
{
@@ -21,4 +102,43 @@ void pb::firsttime_setup()
void pb::paint()
{
render::paint();
+}
+
+void pb::mode_change(int mode)
+{
+}
+
+void pb::toggle_demo()
+{
+ if (demo_mode)
+ {
+ demo_mode = 0;
+ MainTable->Message(1024, 0.0);
+ mode_change(2);
+ pinball::MissTextBox->Clear();
+ auto text = pinball::get_rc_string(24, 0);
+ pinball::InfoTextBox->Display(text, -1.0);
+ }
+ else
+ {
+ replay_level(1);
+ }
+}
+
+void pb::replay_level(int demoMode)
+{
+ demo_mode = demoMode;
+ mode_change(1);
+ //if (options::Options.Music)
+ //midi_play_pb_theme(0);
+ MainTable->Message(1014, static_cast(options::Options.Players));
+}
+
+void pb::ballset(int x, int y)
+{
+}
+
+int pb::frame(int time)
+{
+ return 1;
}
\ No newline at end of file
diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h
index d1d044b..31b3d62 100644
--- a/SpaceCadetPinball/pb.h
+++ b/SpaceCadetPinball/pb.h
@@ -1,13 +1,24 @@
#pragma once
+#include "partman.h"
#include "TPinballTable.h"
class pb
{
public:
+ static int time_ticks;
+ static int ball_speed_limit;
+ static datFileStruct* record_table;
+ static TPinballTable* MainTable;
+
+ static int init();
static void reset_table();
static void firsttime_setup();
static void paint();
-private:
- static TPinballTable* MainTable;
+ static void mode_change(int mode);
+ static void toggle_demo();
+ static void replay_level(int demoMode);
+ static void ballset(int x, int y);
+ static int frame(int time);
+private :
+ static int demo_mode;
};
-
diff --git a/SpaceCadetPinball/pinball.cpp b/SpaceCadetPinball/pinball.cpp
index d3a35e7..8c9ff66 100644
--- a/SpaceCadetPinball/pinball.cpp
+++ b/SpaceCadetPinball/pinball.cpp
@@ -14,8 +14,6 @@ char pinball::DatFileName[300]{};
int pinball::LeftShift = -1;
int pinball::RightShift = -1;
HWND pinball::hwnd_frame = nullptr;
-int pinball::has_focus = 1;
-int pinball::single_step = 0;
char* pinball::get_rc_string(int uID, int a2)
@@ -30,8 +28,8 @@ char* pinball::get_rc_string(int uID, int a2)
int pinball::get_rc_int(int uID, int* dst)
{
- char buffer[50];
- int result = LoadStringA(pinball::hinst, uID, buffer, 255);
+ char buffer[50];
+ int result = LoadStringA(hinst, uID, buffer, 255);
if (!result)
return result;
*dst = atoi(buffer);
@@ -106,3 +104,26 @@ HANDLE pinball::adjust_priority(int priority)
}
return result;
}
+
+int pinball::make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize)
+{
+ int nameSize = GetModuleFileNameA(nullptr, lpFilename, nSize);
+ if (!nameSize || nameSize == nSize)
+ return 1;
+ for (CHAR* i = &lpFilename[nameSize]; i > lpFilename; --i)
+ {
+ if (*i == '\\' || *i == ':')
+ {
+ i[1] = 0;
+ break;
+ }
+ --nameSize;
+ }
+ if (nameSize + 13 < nSize)
+ {
+ lstrcatA(lpFilename, lpString2);
+ return 0;
+ }
+ lstrcatA(lpFilename, "?");
+ return 1;
+}
diff --git a/SpaceCadetPinball/pinball.h b/SpaceCadetPinball/pinball.h
index d7cf97a..f15c00b 100644
--- a/SpaceCadetPinball/pinball.h
+++ b/SpaceCadetPinball/pinball.h
@@ -13,13 +13,12 @@ public:
static int RightShift;
static int LeftShift;
static HWND hwnd_frame;
- static int has_focus;
- static int single_step;
static char* get_rc_string(int uID, int a2);
static int get_rc_int(int uID, int* dst);
static void FindShiftKeys();
static HANDLE adjust_priority(int priority);
+ static int make_path_name(LPSTR lpFilename, LPCSTR lpString2, int nSize = 0x12Cu);
private:
static char getRcBuffer[256 * 6];
static int rc_string_slot;
diff --git a/SpaceCadetPinball/proj.cpp b/SpaceCadetPinball/proj.cpp
new file mode 100644
index 0000000..9bd33d6
--- /dev/null
+++ b/SpaceCadetPinball/proj.cpp
@@ -0,0 +1,62 @@
+#include "pch.h"
+#include "proj.h"
+
+mat4_row_major proj::matrix;
+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];
+ // }
+ //}
+ memcpy(&matrix, mat4x3, sizeof(float) * 4 * 3);
+
+ matrix.Row3.X = 0.0;
+ matrix.Row3.Y = 0.0;
+ matrix.Row3.Z = 0.0;
+ matrix.Row3.W = 1.0;
+
+ d_ = d;
+ centerx = centerX;
+ centery = centerY;
+}
+
+void proj::matrix_vector_multiply(mat4_row_major* mat, vector_type* vec, vector_type* dstVec)
+{
+ const float x = vec->X, y = vec->Y, z = vec->Z;
+ dstVec->X = z * mat->Row0.Z + y * mat->Row0.Y + x * mat->Row0.X + mat->Row0.W;
+ dstVec->Y = z * mat->Row1.Z + y * mat->Row1.Y + x * mat->Row1.X + mat->Row1.W;
+ dstVec->Z = z * mat->Row2.Z + y * mat->Row2.Y + x * mat->Row2.X + mat->Row2.W;
+}
+
+float proj::z_distance(vector_type* vec)
+{
+ vector_type dstVec{};
+ matrix_vector_multiply(&matrix, vec, &dstVec);
+ return maths::magnitude(&dstVec);
+}
+
+void proj::xform_to_2d(vector_type* vec, int* dst)
+{
+ float projCoef;
+ vector_type dstVec2{};
+
+ matrix_vector_multiply(&matrix, vec, &dstVec2);
+ if (0.0 == dstVec2.Z)
+ projCoef = 999999.88f;
+ else
+ projCoef = d_ / dstVec2.Z;
+ dst[0] = static_cast(dstVec2.X * projCoef + centerx);
+ dst[1] = static_cast(dstVec2.Y * projCoef + centery);
+}
+
+void proj::recenter(float centerX, float centerY)
+{
+ centerx = centerX;
+ centery = centerY;
+}
diff --git a/SpaceCadetPinball/proj.h b/SpaceCadetPinball/proj.h
new file mode 100644
index 0000000..8cb4c61
--- /dev/null
+++ b/SpaceCadetPinball/proj.h
@@ -0,0 +1,32 @@
+#pragma once
+#include "maths.h"
+
+struct vector_type4
+{
+ float X;
+ float Y;
+ float Z;
+ float W;
+};
+
+struct mat4_row_major
+{
+ vector_type4 Row0;
+ vector_type4 Row1;
+ vector_type4 Row2;
+ vector_type4 Row3;
+};
+
+
+class proj
+{
+public:
+ static void init(float* mat4x3, float d, float centerX, float centerY);
+ static void matrix_vector_multiply(mat4_row_major* mat, vector_type* vec, vector_type* dstVec);
+ static float z_distance(vector_type* vec);
+ static void xform_to_2d(vector_type* vec, int* dst);
+ static void recenter(float centerX, float centerY);
+private:
+ static mat4_row_major matrix;
+ static float d_, centerx, centery;
+};
diff --git a/SpaceCadetPinball/render.cpp b/SpaceCadetPinball/render.cpp
index 7884145..3e098ff 100644
--- a/SpaceCadetPinball/render.cpp
+++ b/SpaceCadetPinball/render.cpp
@@ -31,7 +31,7 @@ void render::init(gdrv_bitmap8* bmp, float zMin, float zScaler, int width, int h
vscreen.YPosition = 0;
vscreen.XPosition = 0;
gdrv_bitmap8* ballBmp = ball_bitmap;
- while (ballBmp <= &ball_bitmap[20])
+ while (ballBmp < &ball_bitmap[20])
{
gdrv::create_raw_bitmap(ballBmp, 64, 64, 1);
++ballBmp;
diff --git a/SpaceCadetPinball/score.cpp b/SpaceCadetPinball/score.cpp
index a987dc8..e6c42ab 100644
--- a/SpaceCadetPinball/score.cpp
+++ b/SpaceCadetPinball/score.cpp
@@ -48,3 +48,8 @@ scoreStruct* score::dup(scoreStruct* score, int scoreIndex)
memcpy(result, score, sizeof(scoreStruct));
return result;
}
+
+HRSRC score::load_msg_font(LPCSTR lpName)
+{
+ return nullptr;
+}
diff --git a/SpaceCadetPinball/score.h b/SpaceCadetPinball/score.h
index 215e37b..50e22eb 100644
--- a/SpaceCadetPinball/score.h
+++ b/SpaceCadetPinball/score.h
@@ -28,4 +28,5 @@ public:
static int init();
static scoreStruct* create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp);
static scoreStruct* dup(scoreStruct* score, int scoreIndex);
+ static HRSRC load_msg_font(LPCSTR lpName);
};
diff --git a/SpaceCadetPinball/timer.cpp b/SpaceCadetPinball/timer.cpp
new file mode 100644
index 0000000..b277614
--- /dev/null
+++ b/SpaceCadetPinball/timer.cpp
@@ -0,0 +1,38 @@
+#include "pch.h"
+#include "timer.h"
+
+#include "memory.h"
+
+timer_struct timer::timer_struct;
+int timer::setCount;
+
+int timer::init(int count)
+{
+ char* buf; // eax
+ int index; // edx
+ int* v4; // ecx
+
+ buf = memory::allocate(20 * count);
+ timer_struct.buffer1 = buf;
+ if (!buf)
+ return 1;
+ timer_struct.target = 0;
+ index = count - 1;
+ timer_struct.count = count;
+ setCount = 1;
+ if (count - 1 > 0)
+ {
+ v4 = (int*)(buf + 12);
+ do
+ {
+ *v4 = (int)(v4 + 2);
+ v4 += 5;
+ --index;
+ }
+ while (index);
+ }
+ *(int*)&buf[20 * count - 8] = 0;
+ timer_struct.target2 = 0;
+ timer_struct.buffer2 = buf;
+ return 0;
+}
diff --git a/SpaceCadetPinball/timer.h b/SpaceCadetPinball/timer.h
new file mode 100644
index 0000000..3c596a1
--- /dev/null
+++ b/SpaceCadetPinball/timer.h
@@ -0,0 +1,21 @@
+#pragma once
+
+struct __declspec(align(4)) timer_struct
+{
+ int target2;
+ int count;
+ int target;
+ char* buffer2;
+ char* buffer1;
+};
+
+
+class timer
+{
+public:
+ static int init(int count);
+
+private:
+ static timer_struct timer_struct;
+ static int setCount;
+};
diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp
index 13aec7b..3f9c6ca 100644
--- a/SpaceCadetPinball/winmain.cpp
+++ b/SpaceCadetPinball/winmain.cpp
@@ -6,8 +6,13 @@
#include "pinball.h"
#include "options.h"
#include "pb.h"
+#include "Sound.h"
int winmain::iFrostUniqueMsg, winmain::return_value = 0, winmain::bQuit = 0;
+DWORD winmain::then, winmain::now;
+gdrv_bitmap8 winmain::gfr_display{};
+int winmain::DispFrameRate = 1, winmain::DispGRhistory = 1, winmain::single_step = 0;
+int winmain::has_focus = 1, winmain::last_mouse_x, winmain::last_mouse_y, winmain::mouse_down, winmain::no_time_loss;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
@@ -152,36 +157,114 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
}*/
pinball::adjust_priority(options::Options.PriorityAdj);
- auto getTimeFunc = timeGetTime;
const auto startTime = timeGetTime();
MSG wndMessage{};
while (timeGetTime() >= startTime && timeGetTime() - startTime < 2000)
PeekMessageA(&wndMessage, pinball::hwnd_frame, 0, 0, 1u);
+ if (strstr(lpCmdLine, "-demo"))
+ pb::toggle_demo();
+ else
+ pb::replay_level(0);
+
+ DWORD someTimeCounter = 300u, prevTime = 0u;
+ then = timeGetTime();
while (true)
{
- if(false)
+ if (!someTimeCounter)
{
- auto plt = (PALETTEENTRY*)malloc(1024u);
- auto gg = sizeof(LOGPALETTEx256);
- auto pltPtr = &plt[10];
- for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8)
+ someTimeCounter = 300;
+ if (DispFrameRate)
{
- unsigned char blue = i2, redGreen = i2;
- if (i2 > 255)
+ auto curTime = timeGetTime();
+ if (prevTime)
{
- blue = 255;
- redGreen = i1;
- }
+ char buf[60];
+ sprintf_s(buf, "Frames/sec = %02.02f", 300.0f / (static_cast(curTime - prevTime) * 0.001f));
+ SetWindowTextA(pinball::hwnd_frame, buf);
- *pltPtr++ = { redGreen, redGreen, blue };
+ if (DispGRhistory)
+ {
+ if (!gfr_display.BmpBufPtr1)
+ {
+ auto plt = static_cast(malloc(1024u));
+ auto pltPtr = &plt[10];
+ for (int i1 = 0, i2 = 0; i1 < 256 - 10; ++i1, i2 += 8)
+ {
+ unsigned char blue = i2, redGreen = i2;
+ if (i2 > 255)
+ {
+ blue = 255;
+ redGreen = i1;
+ }
+
+ *pltPtr++ = {redGreen, redGreen, blue};
+ }
+ gdrv::display_palette(plt);
+ free(plt);
+ gdrv::create_bitmap(&gfr_display, 400, 15);
+ }
+
+ gdrv::blit(&gfr_display, 0, 0, 0, 0, 300, 10);
+ gdrv::fill_bitmap(&gfr_display, 300, 10, 0, 0, 0);
+ }
+ }
+ prevTime = curTime;
+ }
+ else
+ {
+ prevTime = 0;
}
- gdrv::display_palette(plt);
}
-
+
+ Sound::Idle();
if (!ProcessWindowMessages() || bQuit)
break;
- Sleep(8);
+
+ if (has_focus)
+ {
+ if (mouse_down)
+ {
+ now = timeGetTime();
+ if (now - then >= 2)
+ {
+ POINT Point;
+ GetCursorPos(&Point);
+ pb::ballset(last_mouse_x - Point.x, Point.y - last_mouse_y);
+ SetCursorPos(last_mouse_x, last_mouse_y);
+ }
+ }
+ if (!single_step)
+ {
+ auto curTime = timeGetTime();
+ now = curTime;
+ if (no_time_loss)
+ {
+ then = curTime;
+ no_time_loss = 0;
+ }
+
+ if (curTime == then)
+ {
+ Sleep(8u);
+ }
+ else if (pb::frame(curTime - then))
+ {
+ if (gfr_display.BmpBufPtr1)
+ {
+ auto deltaT = now - then + 10;
+ auto fillChar = static_cast(deltaT);
+ if (deltaT > 236)
+ {
+ fillChar = -7;
+ }
+ gdrv::fill_bitmap(&gfr_display, 1, 10, 299u - someTimeCounter, 0, fillChar);
+ }
+ --someTimeCounter;
+ then = now;
+ }
+ }
+ }
}
return return_value;
@@ -196,7 +279,7 @@ int winmain::ProcessWindowMessages()
{
MSG Msg{}; // [esp+8h] [ebp-1Ch]
- if (pinball::has_focus && !pinball::single_step)
+ if (has_focus && !single_step)
{
while (PeekMessageA(&Msg, nullptr, 0, 0, 1u))
{
diff --git a/SpaceCadetPinball/winmain.h b/SpaceCadetPinball/winmain.h
index d0e4115..c424130 100644
--- a/SpaceCadetPinball/winmain.h
+++ b/SpaceCadetPinball/winmain.h
@@ -1,4 +1,5 @@
#pragma once
+#include "gdrv.h"
class winmain
{
@@ -11,7 +12,10 @@ public:
static HDC _GetDC(HWND hWnd);
static int a_dialog(HINSTANCE hInstance, HWND hWnd);
private:
- static int iFrostUniqueMsg, return_value , bQuit;
+ static int iFrostUniqueMsg, return_value, bQuit, DispFrameRate, DispGRhistory;
+ static int has_focus, single_step, mouse_down, last_mouse_x, last_mouse_y, no_time_loss;
+ static DWORD then, now;
+ static gdrv_bitmap8 gfr_display;
static HDC _BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);
};
diff --git a/SpaceCadetPinball/zdrv.cpp b/SpaceCadetPinball/zdrv.cpp
index 5463949..ae93468 100644
--- a/SpaceCadetPinball/zdrv.cpp
+++ b/SpaceCadetPinball/zdrv.cpp
@@ -38,7 +38,7 @@ int zdrv::destroy_zmap(zmap_header_type* zmap)
void zdrv::fill(zmap_header_type* zmap, int width, int height, int xOff, int yOff, unsigned __int16 fillChar)
{
int fillCharInt = fillChar | (fillChar << 16);
- auto zmapPtr = &zmap->ZPtr1[2 * (xOff + zmap->Stride * (zmap->Height - height - yOff))];
+ auto zmapPtr = &zmap->ZPtr1[xOff + zmap->Stride * (zmap->Height - height - yOff)];
for (int y = height; width > 0 && y > 0; y--)
{