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--) {