From 090beefd071c8fe5c48f4823b9791f9cb93064f9 Mon Sep 17 00:00:00 2001 From: oz Date: Fri, 4 Dec 2020 18:35:47 +0300 Subject: [PATCH] timer v1, ready. winmain uninit. message_handler tweaks. --- Doc/FuncStats.xlsx | Bin 31983 -> 37399 bytes SpaceCadetPinball/Sound.cpp | 14 +- SpaceCadetPinball/Sound.h | 2 + SpaceCadetPinball/SpaceCadetPinball.rc | 34 ++-- SpaceCadetPinball/SpaceCadetPinball.vcxproj | 1 + SpaceCadetPinball/TPinballTable.cpp | 2 +- SpaceCadetPinball/TRamp.cpp | 6 + SpaceCadetPinball/TRamp.h | 2 + SpaceCadetPinball/TTextBox.cpp | 9 +- SpaceCadetPinball/TTextBox.h | 2 +- SpaceCadetPinball/midi.cpp | 13 +- SpaceCadetPinball/midi.h | 1 + SpaceCadetPinball/options.cpp | 25 ++- SpaceCadetPinball/options.h | 1 + SpaceCadetPinball/pb.cpp | 20 ++- SpaceCadetPinball/pb.h | 1 + SpaceCadetPinball/pinball.cpp | 4 +- SpaceCadetPinball/resource.h | 20 ++- SpaceCadetPinball/score.cpp | 4 + SpaceCadetPinball/score.h | 2 +- SpaceCadetPinball/timer.cpp | 163 ++++++++++++++++---- SpaceCadetPinball/timer.h | 29 ++-- SpaceCadetPinball/winmain.cpp | 93 +++++------ 23 files changed, 327 insertions(+), 121 deletions(-) diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index f815ea92ca4f8003f9a74577d3faa26d0fc9a246..91b9aa8a3b1e3cba34b8c69e6cc030e448c65c4c 100644 GIT binary patch delta 30924 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 Nrw0>WY6SXo{|AmcC~g1% delta 25485 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
~Ry(p{xd0o9po=Cdr61EPSjjpUtGekp+Nh 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 D_YZOF diff --git a/SpaceCadetPinball/Sound.cpp b/SpaceCadetPinball/Sound.cpp index 422a790..a3686cf 100644 --- a/SpaceCadetPinball/Sound.cpp +++ b/SpaceCadetPinball/Sound.cpp @@ -1,9 +1,9 @@ #include "pch.h" #include "Sound.h" -int Sound::Init(HINSTANCE hInstance, int voices, void(__stdcall* someFuncPtr)(int, int, int)) +int Sound::Init(HINSTANCE hInstance, int voices, void (__stdcall* someFuncPtr)(int, int, int)) { - return 1; + return 1; } void Sound::Enable(int a1, int a2, int a3) @@ -29,3 +29,13 @@ void Sound::Deactivate() void Sound::Close() { } + +int Sound::SubFactor(int a1, int a2) +{ + return a1 - a2; +} + +int Sound::AddFactor(int a1, int a2) +{ + return a1 + a2; +} diff --git a/SpaceCadetPinball/Sound.h b/SpaceCadetPinball/Sound.h index f25c162..a79b01f 100644 --- a/SpaceCadetPinball/Sound.h +++ b/SpaceCadetPinball/Sound.h @@ -9,4 +9,6 @@ public: static void Activate(); static void Deactivate(); static void Close(); + static int SubFactor(int a1, int a2); + static int AddFactor(int a1, int a2); }; diff --git a/SpaceCadetPinball/SpaceCadetPinball.rc b/SpaceCadetPinball/SpaceCadetPinball.rc index 3f6e72c..a2b5c32 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.rc +++ b/SpaceCadetPinball/SpaceCadetPinball.rc @@ -64,36 +64,36 @@ MENU_1 MENU BEGIN POPUP "&Game" BEGIN - MENUITEM "&New Game\tF2", 101 - MENUITEM "&Launch Ball", 401 - MENUITEM "&Pause/Resume Game\tF3", 402 + MENUITEM "&New Game\tF2", Menu1_New_Game + MENUITEM "&Launch Ball", Menu1_Launch_Ball + MENUITEM "&Pause/Resume Game\tF3", Menu1_Pause_Resume_Game MENUITEM SEPARATOR - MENUITEM "&High Scores...", 103 - MENUITEM "&Demo", 404 - MENUITEM "E&xit", 105 + MENUITEM "&High Scores...", Menu1_High_Scores + MENUITEM "&Demo", Menu1_Demo + MENUITEM "E&xit", Menu1_Exit END POPUP "&Options" BEGIN - MENUITEM "&Full Screen\tF4", 403 - MENUITEM "Select &Table", 405 + MENUITEM "&Full Screen\tF4", Menu1_Full_Screen + MENUITEM "Select &Table", Menu1_Select_Table POPUP "Select &Players" BEGIN - MENUITEM "&1 Player", 408 - MENUITEM "&2 Players", 409 - MENUITEM "&3 Players", 410 - MENUITEM "&4 Players", 411 + MENUITEM "&1 Player", Menu1_1Player + MENUITEM "&2 Players", Menu1_2Players + MENUITEM "&3 Players", Menu1_3Players + MENUITEM "&4 Players", Menu1_4Players END MENUITEM SEPARATOR - MENUITEM "&Sounds", 201 - MENUITEM "&Music", 202 + MENUITEM "&Sounds", Menu1_Sounds + MENUITEM "&Music", Menu1_Music MENUITEM SEPARATOR - MENUITEM "P&layer Controls...\tF8", 406 + MENUITEM "P&layer Controls...\tF8", Menu1_Player_Controls END POPUP "&Help" BEGIN - MENUITEM "&Help Topics\tF1", 301 + MENUITEM "&Help Topics\tF1", Menu1_Help_Topics MENUITEM SEPARATOR - MENUITEM "&About Pinball", 102 + MENUITEM "&About Pinball", Menu1_About_Pinball END END diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj index 1a1a3c5..80735c1 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj @@ -72,6 +72,7 @@ true + false true diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp index a12da8b..ce72c42 100644 --- a/SpaceCadetPinball/TPinballTable.cpp +++ b/SpaceCadetPinball/TPinballTable.cpp @@ -219,7 +219,7 @@ TPinballTable::~TPinballTable() { //if (i) //(*(void(__thiscall**)(TLightGroup*, int))(*(_DWORD*)i + 16))(i, 1); - if (!ListP1->Count()) + //if (!ListP1->Count()) break; } delete ListP2; diff --git a/SpaceCadetPinball/TRamp.cpp b/SpaceCadetPinball/TRamp.cpp index 5143142..6357994 100644 --- a/SpaceCadetPinball/TRamp.cpp +++ b/SpaceCadetPinball/TRamp.cpp @@ -1,2 +1,8 @@ #include "pch.h" #include "TRamp.h" + + +void TRamp::port_draw() +{ + TCollisionComponent::port_draw(); +} diff --git a/SpaceCadetPinball/TRamp.h b/SpaceCadetPinball/TRamp.h index bf57c9f..ca5b7f0 100644 --- a/SpaceCadetPinball/TRamp.h +++ b/SpaceCadetPinball/TRamp.h @@ -8,4 +8,6 @@ public: TRamp(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false) { } + + void port_draw() override; }; diff --git a/SpaceCadetPinball/TTextBox.cpp b/SpaceCadetPinball/TTextBox.cpp index 53b9d89..04cffb3 100644 --- a/SpaceCadetPinball/TTextBox.cpp +++ b/SpaceCadetPinball/TTextBox.cpp @@ -50,8 +50,9 @@ int TTextBox::Message(int code, float value) return 0; } -void TTextBox::TimerExpired(int a2, TTextBox* tb) +void TTextBox::TimerExpired(int timerId, void* caller) { + auto tb = static_cast(caller); TTextBoxMessage* message = tb->Message1; tb->Timer = 0; if (message) @@ -117,7 +118,7 @@ void TTextBox::Display(char* text, float time) if (time == -1.0) Timer = -1; else - Timer = timer::set(time, (int)this, (int)TimerExpired); + Timer = timer::set(time, this, TimerExpired); } } else @@ -205,11 +206,11 @@ void TTextBox::Draw() int timer; if (timeLeft >= 0.25f) { - timer = timer::set(timeLeft, (int)this2, (int)TimerExpired); + timer = timer::set(timeLeft, this2, TimerExpired); } else { - timer = timer::set(0.25, (int)this2, (int)TimerExpired); + timer = timer::set(0.25, this2, TimerExpired); } this2->Timer = timer; goto LABEL_18; diff --git a/SpaceCadetPinball/TTextBox.h b/SpaceCadetPinball/TTextBox.h index da54dea..505f9fa 100644 --- a/SpaceCadetPinball/TTextBox.h +++ b/SpaceCadetPinball/TTextBox.h @@ -24,5 +24,5 @@ public: void Display(char* text, float time); void Draw(); - static void TimerExpired(int a2, TTextBox* tb); + static void TimerExpired(int timerId, void* tb); }; diff --git a/SpaceCadetPinball/midi.cpp b/SpaceCadetPinball/midi.cpp index 61a4478..2ea232f 100644 --- a/SpaceCadetPinball/midi.cpp +++ b/SpaceCadetPinball/midi.cpp @@ -3,20 +3,25 @@ MCIERROR midi::play_pb_theme(int flag) { - return MCIERROR(); + return MCIERROR(); } MCIERROR midi::music_stop() { - return MCIERROR(); + return MCIERROR(); } int midi::music_init(HWND hwnd) { - return 1; + return 1; } MCIERROR midi::restart_midi_seq(int param) { - return MCIERROR(); + return MCIERROR(); +} + +MCIERROR midi::music_shutdown() +{ + return MCIERROR(); } diff --git a/SpaceCadetPinball/midi.h b/SpaceCadetPinball/midi.h index 335574e..79a1ca1 100644 --- a/SpaceCadetPinball/midi.h +++ b/SpaceCadetPinball/midi.h @@ -6,4 +6,5 @@ public: static MCIERROR music_stop(); static int music_init(HWND hwnd); static MCIERROR restart_midi_seq(int param); + static MCIERROR music_shutdown(); }; diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index d591afa..5fe9486 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -5,6 +5,7 @@ #include "memory.h" #include "midi.h" #include "pinball.h" +#include "resource.h" #include "Sound.h" #include "winmain.h" @@ -68,7 +69,7 @@ void options::init(HMENU menuHandle) { if (MenuHandle) { - DeleteMenu(MenuHandle, 0x195u, 0); + DeleteMenu(MenuHandle, Menu1_Select_Table, 0); DrawMenuBar(winmain::hwnd_frame); } } @@ -76,6 +77,20 @@ void options::init(HMENU menuHandle) } } +void options::uninit() +{ + set_int(nullptr, "Sounds", Options.Sounds); + set_int(nullptr, "Music", Options.Music); + set_int(nullptr, "FullScreen", Options.FullScreen); + set_int(nullptr, "Players", Options.Players); + set_int(nullptr, "Left Flippper key", Options.LeftFlipperKey); + set_int(nullptr, "Right Flipper key", Options.RightFlipperKey); + set_int(nullptr, "Plunger key", Options.PlungerKey); + set_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey); + set_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey); + set_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey); +} + void options::path_init(LPCSTR regPath) { char* buf = memory::allocate(lstrlenA(regPath) + 1); @@ -207,13 +222,13 @@ void options::toggle(UINT uIDCheckItem) int newValue; switch (uIDCheckItem) { - case 0xC9u: + case Menu1_Sounds: newValue = Options.Sounds == 0; Options.Sounds = Options.Sounds == 0; Sound::Enable(0, 7, newValue); menu_check(uIDCheckItem, newValue); return; - case 0xCAu: + case Menu1_Music: newValue = Options.Music == 0; Options.Music = Options.Music == 0; if (!newValue) @@ -222,7 +237,7 @@ void options::toggle(UINT uIDCheckItem) midi::play_pb_theme(0); menu_check(uIDCheckItem, newValue); return; - case 0x193u: + case Menu1_Full_Screen: newValue = Options.FullScreen == 0; Options.FullScreen = Options.FullScreen == 0; fullscrn::set_screen_mode(newValue); @@ -232,7 +247,7 @@ void options::toggle(UINT uIDCheckItem) if (uIDCheckItem > 407 && uIDCheckItem <= 411) { Options.Players = uIDCheckItem - 407; - menu_check(0x198u, uIDCheckItem == 408); + menu_check(0x198u, Options.Players == 1); menu_check(0x199u, Options.Players == 2); menu_check(0x19Au, Options.Players == 3); menu_check(0x19Bu, Options.Players == 4); diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h index 19cc41a..95037ae 100644 --- a/SpaceCadetPinball/options.h +++ b/SpaceCadetPinball/options.h @@ -27,6 +27,7 @@ class options { public: static void init(HMENU menuHandle); + static void uninit(); static void path_init(LPCSTR regPath); static void path_uninit(); static int get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue); diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index b1e1cca..5d161d4 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -58,7 +58,8 @@ 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, (char)0xff); // temp + gdrv::fill_bitmap(&render::vscreen, render::vscreen.Width, render::vscreen.Height, 0, 0, + static_cast(0xff)); // temp gdrv::copy_bitmap( &render::vscreen, backgroundBmp->Width, @@ -91,6 +92,21 @@ int pb::init() return 0; } +int pb::uninit() +{ + score::unload_msg_font(); + loader::unload(); + partman::unload_records(record_table); + //high_score_write(highscore_table, (int)&pb_state); + if (MainTable) + delete MainTable; + MainTable = nullptr; + gdrv::get_focus(); + timer::uninit(); + render::uninit(); + return 0; +} + void pb::reset_table() { if (MainTable) @@ -166,7 +182,7 @@ int pb::frame(int time) v2 = 0.0; nudge_count = v2; }*/ - //timer::check(); + timer::check(); render::update(); //score::update(MainTable->Score1); /*if (!MainTable->UnknownP83) diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 8a644bd..f103533 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -12,6 +12,7 @@ public: static TPinballTable* MainTable; static int init(); + static int uninit(); static void reset_table(); static void firsttime_setup(); static void paint(); diff --git a/SpaceCadetPinball/pinball.cpp b/SpaceCadetPinball/pinball.cpp index 2554b0f..92cf9e3 100644 --- a/SpaceCadetPinball/pinball.cpp +++ b/SpaceCadetPinball/pinball.cpp @@ -25,7 +25,7 @@ char* pinball::get_rc_string(int uID, int a2) int pinball::get_rc_int(int uID, int* dst) { - char buffer[50]; + char buffer[255]; int result = LoadStringA(winmain::hinst, uID, buffer, 255); if (!result) return result; @@ -38,7 +38,7 @@ void pinball::FindShiftKeys() { signed int i; // esi int rightShift; // eax - CHAR stringBuf[10]; // [esp+Ch] [ebp-18h] + CHAR stringBuf[20]; // [esp+Ch] [ebp-18h] RightShift = -1; LeftShift = -1; diff --git a/SpaceCadetPinball/resource.h b/SpaceCadetPinball/resource.h index 608d062..8cb7725 100644 --- a/SpaceCadetPinball/resource.h +++ b/SpaceCadetPinball/resource.h @@ -104,10 +104,14 @@ #define IDS_STRING200 99 #define IDS_STRING201 100 #define IDS_STRING202 101 +#define Menu1_New_Game 101 #define IDS_STRING203 102 +#define Menu1_About_Pinball 102 #define IDS_STRING204 103 +#define Menu1_High_Scores 103 #define IDS_STRING205 104 #define IDS_STRING206 105 +#define Menu1_Exit 105 #define IDS_STRING207 106 #define IDS_STRING208 107 #define IDS_STRING209 108 @@ -191,13 +195,27 @@ #define IDS_STRING287 187 #define IDS_STRING288 188 #define IDS_STRING289 189 +#define Menu1_Sounds 201 +#define Menu1_Music 202 +#define Menu1_Help_Topics 301 +#define Menu1_Launch_Ball 401 +#define Menu1_Pause_Resume_Game 402 +#define Menu1_Full_Screen 403 +#define Menu1_Demo 404 +#define Menu1_Select_Table 405 +#define Menu1_Player_Controls 406 +#define Menu1_1Player 408 +#define Menu1_2Players 409 +#define Menu1_3Players 410 +#define Menu1_4Players 411 +#define ID_GAME_D 40003 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 201 -#define _APS_NEXT_COMMAND_VALUE 40002 +#define _APS_NEXT_COMMAND_VALUE 40004 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif diff --git a/SpaceCadetPinball/score.cpp b/SpaceCadetPinball/score.cpp index 5f5a2eb..177f210 100644 --- a/SpaceCadetPinball/score.cpp +++ b/SpaceCadetPinball/score.cpp @@ -54,3 +54,7 @@ HRSRC score::load_msg_font(LPCSTR lpName) { return nullptr; } + +void score::unload_msg_font() +{ +} diff --git a/SpaceCadetPinball/score.h b/SpaceCadetPinball/score.h index 0424d9f..a991324 100644 --- a/SpaceCadetPinball/score.h +++ b/SpaceCadetPinball/score.h @@ -24,7 +24,6 @@ struct scoreStruct struct score_msg_font_type { - }; class score @@ -35,4 +34,5 @@ public: static scoreStruct* create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp); static scoreStruct* dup(scoreStruct* score, int scoreIndex); static HRSRC load_msg_font(LPCSTR lpName); + static void unload_msg_font(); }; diff --git a/SpaceCadetPinball/timer.cpp b/SpaceCadetPinball/timer.cpp index 636ee58..2280e70 100644 --- a/SpaceCadetPinball/timer.cpp +++ b/SpaceCadetPinball/timer.cpp @@ -2,47 +2,152 @@ #include "timer.h" #include "memory.h" +#include "pb.h" -timer_struct timer::timer_struct; -int timer::setCount; +timer_struct timer::timerStruct{}; +int timer::set_count; int timer::init(int count) { - char* buf; // eax - int index; // edx - int* v4; // ecx - - buf = memory::allocate(20 * count); - timer_struct.buffer1 = buf; + auto buf = (timer_sub_struct*)memory::allocate(sizeof(timer_sub_struct) * count); + timerStruct.TimerMem = buf; if (!buf) return 1; - timer_struct.target = 0; - index = count - 1; - timer_struct.count = count; - setCount = 1; - if (count - 1 > 0) + timerStruct.Count = 0; + timerStruct.MaxCount = count; + set_count = 1; + + for (int index = 0; index < count - 1; index++) + buf[index].NextTimer = &buf[index + 1]; + buf[count - 1].NextTimer = nullptr; + + timerStruct.NextTimer = nullptr; + timerStruct.LastTimer = buf; + return 0; +} + +void timer::uninit() +{ + if (timerStruct.TimerMem) + memory::free(timerStruct.TimerMem); + timerStruct.TimerMem = nullptr; +} + +int timer::kill(int timerId) +{ + timer_sub_struct* next = timerStruct.NextTimer; + int index = 0; + timer_sub_struct* current = nullptr; + if (timerStruct.Count <= 0) + return 0; + while (timerId != next->TimerId) { - v4 = (int*)(buf + 12); - do - { - *v4 = (int)(v4 + 2); - v4 += 5; - --index; - } - while (index); + ++index; + current = next; + next = next->NextTimer; + if (index >= timerStruct.Count) + return 0; } - *(int*)&buf[20 * count - 8] = 0; - timer_struct.target2 = 0; - timer_struct.buffer2 = buf; - return 0; + if (current) + current->NextTimer = next->NextTimer; + else + timerStruct.NextTimer = next->NextTimer; + + --timerStruct.Count; + next->NextTimer = timerStruct.LastTimer; + timerStruct.LastTimer = next; + return timerId; } -int timer::kill(int timer) +int timer::set(float time, void* caller, void (* callback)(int, void*)) { - return 0; + if (timerStruct.Count >= timerStruct.MaxCount) + return 0; + + /*timerStruct.LastTimer->NextTimer = nullptr; + timerStruct.LastTimer = timerStruct.LastTimer->NextTimer;*/ + + auto lastNext = timerStruct.LastTimer->NextTimer; + timerStruct.LastTimer->NextTimer = nullptr; + timerStruct.LastTimer = lastNext; + + auto prev = timerStruct.NextTimer; + auto current = timerStruct.NextTimer; + + auto targetTime = pb::time_ticks + static_cast(time * 1000.0f); + for (int index = 0; index < timerStruct.Count && targetTime >= current->TargetTime; ++index) + { + prev = current; + current = current->NextTimer; + } + + auto last = timerStruct.LastTimer; + if (current != prev) + { + timerStruct.LastTimer->NextTimer = prev->NextTimer; + prev->NextTimer = last; + } + else + { + timerStruct.LastTimer->NextTimer = timerStruct.NextTimer; + timerStruct.NextTimer = last; + } + + last->Caller = caller; + last->Callback = callback; + last->TimerId = set_count; + last->TargetTime = targetTime; + timerStruct.Count++; + + set_count++; + if (set_count <= 0) + set_count = 1; + return last->TimerId; } -int timer::set(float time, int caller, int callback) +int timer::check() { - return 0; + timer_sub_struct curCopy{}; + timer_sub_struct* current = timerStruct.NextTimer; + int index = 0; + if (timerStruct.NextTimer) + { + while (pb::time_ticks >= current->TargetTime) + { + --timerStruct.Count; + memcpy(&curCopy, current, sizeof curCopy); + timer_sub_struct** nextPtr = ¤t->NextTimer; + current = current->NextTimer; + timerStruct.NextTimer = current; + *nextPtr = timerStruct.LastTimer; + timerStruct.LastTimer = current; + if (curCopy.Callback != nullptr) + { + curCopy.Callback(curCopy.TimerId, curCopy.Caller); + current = timerStruct.NextTimer; + } + ++index; + if (index > 1) + break; + if (!current) + return index; + } + while (current && pb::time_ticks >= current->TargetTime + 100) + { + --timerStruct.Count; + memcpy(&curCopy, current, sizeof curCopy); + timer_sub_struct** nextPtr = ¤t->NextTimer; + current = current->NextTimer; + timerStruct.NextTimer = current; + *nextPtr = timerStruct.LastTimer; + timerStruct.LastTimer = current; + if (curCopy.Callback != nullptr) + { + curCopy.Callback(curCopy.TimerId, curCopy.Caller); + current = timerStruct.NextTimer; + } + ++index; + } + } + return index; } diff --git a/SpaceCadetPinball/timer.h b/SpaceCadetPinball/timer.h index 0e427e5..2834896 100644 --- a/SpaceCadetPinball/timer.h +++ b/SpaceCadetPinball/timer.h @@ -1,12 +1,21 @@ #pragma once +struct __declspec(align(4)) timer_sub_struct +{ + int TargetTime; + void* Caller; + void (* Callback)(int, void*); + timer_sub_struct* NextTimer; + int TimerId; +}; + struct __declspec(align(4)) timer_struct { - int target2; - int count; - int target; - char* buffer2; - char* buffer1; + timer_sub_struct* NextTimer; + int MaxCount; + int Count; + timer_sub_struct* LastTimer; + timer_sub_struct* TimerMem; }; @@ -14,10 +23,12 @@ class timer { public: static int init(int count); - static int kill(int timer); - static int set(float time, int caller, int callback); + static void uninit(); + static int kill(int timerId); + static int set(float time, void* caller, void (* callback)(int, void*)); + static int check(); private: - static timer_struct timer_struct; - static int setCount; + static timer_struct timerStruct; + static int set_count; }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index d1d046e..ec8631d 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -8,6 +8,7 @@ #include "options.h" #include "pb.h" #include "Sound.h" +#include "resource.h" HINSTANCE winmain::hinst = nullptr; HWND winmain::hwnd_frame = nullptr; @@ -68,6 +69,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi if (tmpBuf2) { char Buffer[40]; + bool setOption = false; for (int i = 0; i < 32700; ++i) { sprintf_s(Buffer, "Table%d", i); @@ -76,12 +78,15 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi break; options::get_string(tmpBuf, "Table Name", tmpBuf2, pinball::WindowName, 500); if (!lstrcmpA(tmpBuf2, pinball::get_rc_string(169, 0))) - goto LABEL_15; + { + setOption = false; + break; + } if (!*tmpBuf2) break; } - options::set_string(nullptr, Buffer, regSpaceCadet); - LABEL_15: + if (setOption) + options::set_string(nullptr, Buffer, regSpaceCadet); memory::free(tmpBuf2); } memory::free(tmpBuf); @@ -111,7 +116,8 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi options::get_string(regSpaceCadet, "Pinball Data", DatFileName, pinball::get_rc_string(168, 0), 300); iFrostUniqueMsg = RegisterWindowMessageA("PinballThemeSwitcherUniqueMsgString"); - auto windowHandle = FindWindowA(pinball::get_rc_string(167, 0), nullptr); + auto windowClass = pinball::get_rc_string(167, 0); + auto windowHandle = FindWindowA(windowClass, nullptr); if (windowHandle) { SendMessageA(windowHandle, iFrostUniqueMsg, 0, 0); @@ -125,8 +131,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi picce.dwSize = 8; picce.dwICC = 5885; InitCommonControlsEx(&picce); - - auto windowClass = pinball::get_rc_string(167, 0); + WNDCLASSA WndClass{}; WndClass.style = 4104; WndClass.lpfnWndProc = message_handler; @@ -178,7 +183,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi pinball::adjust_priority(options::Options.PriorityAdj); const auto startTime = timeGetTime(); MSG wndMessage{}; - while (timeGetTime() >= startTime && timeGetTime() - startTime < 0)// Don't wait for now, was 2000 + while (timeGetTime() >= startTime && timeGetTime() - startTime < 0) // Don't wait for now, was 2000 PeekMessageA(&wndMessage, hwnd_frame, 0, 0, 1u); if (strstr(lpCmdLine, "-demo")) @@ -277,7 +282,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi { fillChar = -7; } - gdrv::fill_bitmap(&gfr_display, 1, 10, 299u - someTimeCounter, 0, fillChar); + gdrv::fill_bitmap(&gfr_display, 1, 10, 299 - someTimeCounter, 0, fillChar); } --someTimeCounter; then = now; @@ -286,6 +291,15 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi } } + gdrv::destroy_bitmap(&gfr_display); + options::uninit(); + midi::music_shutdown(); + pb::uninit(); + Sound::Close(); + gdrv::uninit(); + DestroyWindow(hwnd_frame); + options::path_uninit(); + UnregisterClassA(windowClass, hinst); return return_value; } @@ -499,23 +513,18 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP no_time_loss = 1; switch (wParam) { - case 0x191u: + case Menu1_Launch_Ball: end_pause(); pb::launch_ball(); break; - case 0x192u: + case Menu1_Pause_Resume_Game: pause(); break; - case 0x193u: - if (!single_step) - pause(); - options::toggle(wParam); - break; - case 0x194u: + case Menu1_Demo: end_pause(); pb::toggle_demo(); break; - case 0x195u: + case Menu1_Select_Table: { if (!single_step) pause(); @@ -548,55 +557,53 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP } break; } - case 0x196u: - if (!single_step) - pause(); - options::keyboard(); - break; - case 0x198u: - case 0x199u: - case 0x19Au: - case 0x19Bu: + case Menu1_1Player: + case Menu1_2Players: + case Menu1_3Players: + case Menu1_4Players: options::toggle(wParam); new_game(); break; - case 301: + case Menu1_Help_Topics: if (!single_step) pause(); help_introduction(hinst, hWnd); - return DefWindowProcA(hWnd, Msg, wParam, lParam); - case 0x6A: + break; + case 106: // End game button? pb::end_game(); - return DefWindowProcA(hWnd, Msg, wParam, lParam); - case 201: - case 202: + break; + case Menu1_Full_Screen: + case Menu1_Sounds: + case Menu1_Music: if (!single_step) pause(); options::toggle(wParam); break; - case 204: + case Menu1_Player_Controls: + case 204: // Second controls button? if (!single_step) pause(); options::keyboard(); break; - case 0x69u: - PostMessageA(hWnd, 0x12u, 0, 0); - return DefWindowProcA(hWnd, Msg, wParam, lParam); - case 0x65u: + case Menu1_Exit: + PostMessageA(hWnd, WM_QUIT, 0, 0); + break; + case Menu1_New_Game: new_game(); - return DefWindowProcA(hWnd, Msg, wParam, lParam); - case 0x66u: + break; + case Menu1_About_Pinball: if (!single_step) pause(); a_dialog(hinst, hWnd); - return DefWindowProcA(hWnd, Msg, wParam, lParam); - case 0x67u: + break; + case Menu1_High_Scores: if (!single_step) pause(); pb::high_scores(); - return DefWindowProcA(hWnd, Msg, wParam, lParam); - case 1: + break; + case 1: // Unknown button midi::restart_midi_seq(lParam); + break; default: break; }