diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx
index 91b9aa8..05242d5 100644
Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
index 80735c1..b9c8cc9 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
@@ -158,6 +158,7 @@
+
@@ -219,6 +220,7 @@
+
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
index 146dbad..ab37c36 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
@@ -210,6 +210,9 @@
Header Files\TPinballComponent
+
+ Header Files
+
@@ -386,6 +389,9 @@
Source Files\TPinballComponent
+
+ Source Files
+
diff --git a/SpaceCadetPinball/high_score.cpp b/SpaceCadetPinball/high_score.cpp
new file mode 100644
index 0000000..e00ab80
--- /dev/null
+++ b/SpaceCadetPinball/high_score.cpp
@@ -0,0 +1,16 @@
+#include "pch.h"
+#include "high_score.h"
+
+int high_score::read(CHAR* table, int* ptrToSmth)
+{
+ return 0;
+}
+
+int high_score::write(CHAR* table, int* ptrToSmth)
+{
+ return 0;
+}
+
+void high_score::show_high_score_dialog(CHAR* table)
+{
+}
diff --git a/SpaceCadetPinball/high_score.h b/SpaceCadetPinball/high_score.h
new file mode 100644
index 0000000..667905a
--- /dev/null
+++ b/SpaceCadetPinball/high_score.h
@@ -0,0 +1,8 @@
+#pragma once
+class high_score
+{
+public:
+ static int read(CHAR* table, int* ptrToSmth);
+ static int write(CHAR* table, int* ptrToSmth);
+ static void show_high_score_dialog(CHAR* table);
+};
diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp
index 5fe9486..cc5ff64 100644
--- a/SpaceCadetPinball/options.cpp
+++ b/SpaceCadetPinball/options.cpp
@@ -53,14 +53,14 @@ void options::init(HMENU menuHandle)
Options.LeftTableBumpKey = get_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey);
Options.RightTableBumpKey = get_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey);
Options.BottomTableBumpKey = get_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey);
- menu_check(0xC9u, Options.Sounds);
+ menu_check(Menu1_Sounds, Options.Sounds);
Sound::Enable(0, 7, Options.Sounds);
- menu_check(0xCAu, Options.Music);
- menu_check(0x193u, Options.FullScreen);
- menu_check(0x198u, Options.Players == 1);
- menu_check(0x199u, Options.Players == 2);
- menu_check(0x19Au, Options.Players == 3);
- menu_check(0x19Bu, Options.Players == 4);
+ menu_check(Menu1_Music, Options.Music);
+ menu_check(Menu1_Full_Screen, Options.FullScreen);
+ menu_check(Menu1_1Player, Options.Players == 1);
+ menu_check(Menu1_2Players, Options.Players == 2);
+ menu_check(Menu1_3Players, Options.Players == 3);
+ menu_check(Menu1_4Players, Options.Players == 4);
auto tmpBuf = memory::allocate(0x1F4u);
if (tmpBuf)
{
@@ -247,10 +247,10 @@ void options::toggle(UINT uIDCheckItem)
if (uIDCheckItem > 407 && uIDCheckItem <= 411)
{
Options.Players = uIDCheckItem - 407;
- menu_check(0x198u, Options.Players == 1);
- menu_check(0x199u, Options.Players == 2);
- menu_check(0x19Au, Options.Players == 3);
- menu_check(0x19Bu, Options.Players == 4);
+ menu_check(Menu1_1Player, Options.Players == 1);
+ menu_check(Menu1_2Players, Options.Players == 2);
+ menu_check(Menu1_3Players, Options.Players == 3);
+ menu_check(Menu1_4Players, Options.Players == 4);
}
}
diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp
index 5d161d4..047d077 100644
--- a/SpaceCadetPinball/pb.cpp
+++ b/SpaceCadetPinball/pb.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include "pb.h"
+#include "high_score.h"
#include "memory.h"
#include "pinball.h"
#include "proj.h"
@@ -11,12 +12,14 @@
#include "options.h"
#include "timer.h"
#include "winmain.h"
+#include "resource.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;
+ ball_speed_limit, pb::state;
float pb::time_now, pb::time_next;
+char pb::highscore_table[32];
int pb::init()
{
@@ -58,8 +61,7 @@ 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,
- static_cast(0xff)); // temp
+ gdrv::fill_bitmap(&render::vscreen, render::vscreen.Width, render::vscreen.Height, 0, 0, '\xFF'); // temp
gdrv::copy_bitmap(
&render::vscreen,
backgroundBmp->Width,
@@ -84,7 +86,7 @@ int pb::init()
MainTable = new TPinballTable();
- //high_score_read(highscore_table, (int)&pb_state);
+ high_score::read(highscore_table, &state);
//v11 = *(float*)((char*)MainTable->ListP2.ListPtr->Array[0] + 154);
//ball_speed_limit = v11 * 200.0;
@@ -97,7 +99,7 @@ int pb::uninit()
score::unload_msg_font();
loader::unload();
partman::unload_records(record_table);
- //high_score_write(highscore_table, (int)&pb_state);
+ high_score::write(highscore_table, &state);
if (MainTable)
delete MainTable;
MainTable = nullptr;
@@ -128,6 +130,52 @@ void pb::paint()
void pb::mode_change(int mode)
{
+ switch (mode)
+ {
+ case 1:
+ if (demo_mode)
+ {
+ options::menu_set(Menu1_Launch_Ball, 0);
+ options::menu_set(Menu1_High_Scores, 0);
+ options::menu_check(Menu1_Demo, 1);
+ if (MainTable)
+ {
+ /*v2 = MainTable->UnknownP48;
+ if (v2)
+ *(_BYTE*)(v2 + 5) = 1;*/
+ }
+ }
+ else
+ {
+ options::menu_set(Menu1_High_Scores, 1);
+ options::menu_set(Menu1_Launch_Ball, 1);
+ options::menu_check(Menu1_Demo, 0);
+ if (MainTable)
+ {
+ /*v1 = MainTable->UnknownP48;
+ if (v1)
+ *(_BYTE*)(v1 + 5) = 0;*/
+ }
+ }
+ break;
+ case 2:
+ options::menu_set(Menu1_Launch_Ball, 0);
+ if (!demo_mode)
+ {
+ options::menu_set(Menu1_High_Scores, 1);
+ options::menu_check(Menu1_Demo, 0);
+ }
+ if (MainTable && MainTable->LightGroup)
+ MainTable->LightGroup->Message(29, 1.4f);
+ break;
+ case 3:
+ case 4:
+ options::menu_set(Menu1_Launch_Ball, 0);
+ options::menu_set(Menu1_High_Scores, 0);
+ mode_countdown_ = 5000;
+ break;
+ }
+ game_mode = mode;
}
void pb::toggle_demo()
@@ -151,8 +199,8 @@ void pb::replay_level(int demoMode)
{
demo_mode = demoMode;
mode_change(1);
- //if (options::Options.Music)
- midi::play_pb_theme(0);
+ if (options::Options.Music)
+ midi::play_pb_theme(0);
MainTable->Message(1014, static_cast(options::Options.Players));
}
@@ -388,6 +436,7 @@ int pb::cheat_bump_rank()
void pb::launch_ball()
{
+ MainTable->Plunger->Message(1017, 0.0f);
}
int pb::end_game()
@@ -397,4 +446,5 @@ int pb::end_game()
void pb::high_scores()
{
+ high_score::show_high_score_dialog(highscore_table);
}
diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h
index f103533..18bc3f2 100644
--- a/SpaceCadetPinball/pb.h
+++ b/SpaceCadetPinball/pb.h
@@ -35,4 +35,6 @@ public:
private :
static int demo_mode, mode_countdown_;
static float time_now, time_next;
+ static char highscore_table[32];
+ static int state;
};
diff --git a/SpaceCadetPinball/timer.cpp b/SpaceCadetPinball/timer.cpp
index 2280e70..2420868 100644
--- a/SpaceCadetPinball/timer.cpp
+++ b/SpaceCadetPinball/timer.cpp
@@ -4,128 +4,124 @@
#include "memory.h"
#include "pb.h"
-timer_struct timer::timerStruct{};
-int timer::set_count;
+int timer::SetCount;
+timer_struct* timer::ActiveList;
+int timer::MaxCount;
+int timer::Count;
+timer_struct* timer::FreeList;
+timer_struct* timer::TimerBuffer;
int timer::init(int count)
{
- auto buf = (timer_sub_struct*)memory::allocate(sizeof(timer_sub_struct) * count);
- timerStruct.TimerMem = buf;
+ auto buf = (timer_struct*)memory::allocate(sizeof(timer_struct) * count);
+ TimerBuffer = buf;
if (!buf)
return 1;
- timerStruct.Count = 0;
- timerStruct.MaxCount = count;
- set_count = 1;
+ Count = 0;
+ MaxCount = count;
+ SetCount = 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;
+ ActiveList = nullptr;
+ FreeList = buf;
return 0;
}
void timer::uninit()
{
- if (timerStruct.TimerMem)
- memory::free(timerStruct.TimerMem);
- timerStruct.TimerMem = nullptr;
+ if (TimerBuffer)
+ memory::free(TimerBuffer);
+ TimerBuffer = nullptr;
}
int timer::kill(int timerId)
{
- timer_sub_struct* next = timerStruct.NextTimer;
+ timer_struct* current = ActiveList;
int index = 0;
- timer_sub_struct* current = nullptr;
- if (timerStruct.Count <= 0)
+ timer_struct* prev = nullptr;
+ if (Count <= 0)
return 0;
- while (timerId != next->TimerId)
+ while (timerId != current->TimerId)
{
++index;
- current = next;
- next = next->NextTimer;
- if (index >= timerStruct.Count)
+ prev = current;
+ current = current->NextTimer;
+ if (index >= Count)
return 0;
}
- if (current)
- current->NextTimer = next->NextTimer;
+ if (prev)
+ prev->NextTimer = current->NextTimer;
else
- timerStruct.NextTimer = next->NextTimer;
+ ActiveList = current->NextTimer;
- --timerStruct.Count;
- next->NextTimer = timerStruct.LastTimer;
- timerStruct.LastTimer = next;
+ --Count;
+ current->NextTimer = FreeList;
+ FreeList = current;
return timerId;
}
int timer::set(float time, void* caller, void (* callback)(int, void*))
{
- if (timerStruct.Count >= timerStruct.MaxCount)
+ if (Count >= MaxCount)
return 0;
- /*timerStruct.LastTimer->NextTimer = nullptr;
- timerStruct.LastTimer = timerStruct.LastTimer->NextTimer;*/
+ auto timer = FreeList;
+ FreeList = timer->NextTimer;
+ timer->NextTimer = nullptr;
- auto lastNext = timerStruct.LastTimer->NextTimer;
- timerStruct.LastTimer->NextTimer = nullptr;
- timerStruct.LastTimer = lastNext;
-
- auto prev = timerStruct.NextTimer;
- auto current = timerStruct.NextTimer;
+ auto prev = ActiveList;
+ auto current = ActiveList;
auto targetTime = pb::time_ticks + static_cast(time * 1000.0f);
- for (int index = 0; index < timerStruct.Count && targetTime >= current->TargetTime; ++index)
+ for (int index = 0; index < 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;
+ timer->NextTimer = prev->NextTimer;
+ prev->NextTimer = timer;
}
else
{
- timerStruct.LastTimer->NextTimer = timerStruct.NextTimer;
- timerStruct.NextTimer = last;
+ timer->NextTimer = ActiveList;
+ ActiveList = timer;
}
- last->Caller = caller;
- last->Callback = callback;
- last->TimerId = set_count;
- last->TargetTime = targetTime;
- timerStruct.Count++;
+ timer->Caller = caller;
+ timer->Callback = callback;
+ timer->TimerId = SetCount;
+ timer->TargetTime = targetTime;
+ Count++;
- set_count++;
- if (set_count <= 0)
- set_count = 1;
- return last->TimerId;
+ SetCount++;
+ if (SetCount <= 0)
+ SetCount = 1;
+ return timer->TimerId;
}
int timer::check()
{
- timer_sub_struct curCopy{};
- timer_sub_struct* current = timerStruct.NextTimer;
+ timer_struct* current = ActiveList;
int index = 0;
- if (timerStruct.NextTimer)
+ if (ActiveList)
{
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;
- }
+ --Count;
+ // Advance active list, move current to free
+ ActiveList = current->NextTimer;
+ current->NextTimer = FreeList;
+ FreeList = current;
+ if (current->Callback != nullptr)
+ current->Callback(current->TimerId, current->Caller);
+
+ current = ActiveList;
++index;
if (index > 1)
break;
@@ -134,18 +130,14 @@ int timer::check()
}
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;
- }
+ --Count;
+ ActiveList = current->NextTimer;
+ current->NextTimer = FreeList;
+ FreeList = current;
+ if (current->Callback != nullptr)
+ current->Callback(current->TimerId, current->Caller);
+
+ current = ActiveList;
++index;
}
}
diff --git a/SpaceCadetPinball/timer.h b/SpaceCadetPinball/timer.h
index 2834896..d06b34b 100644
--- a/SpaceCadetPinball/timer.h
+++ b/SpaceCadetPinball/timer.h
@@ -1,24 +1,14 @@
#pragma once
-struct __declspec(align(4)) timer_sub_struct
+struct __declspec(align(4)) timer_struct
{
int TargetTime;
void* Caller;
void (* Callback)(int, void*);
- timer_sub_struct* NextTimer;
+ timer_struct* NextTimer;
int TimerId;
};
-struct __declspec(align(4)) timer_struct
-{
- timer_sub_struct* NextTimer;
- int MaxCount;
- int Count;
- timer_sub_struct* LastTimer;
- timer_sub_struct* TimerMem;
-};
-
-
class timer
{
public:
@@ -29,6 +19,10 @@ public:
static int check();
private:
- static timer_struct timerStruct;
- static int set_count;
+ static int SetCount;
+ static timer_struct* ActiveList;
+ static int MaxCount;
+ static int Count;
+ static timer_struct* FreeList;
+ static timer_struct* TimerBuffer;
};
diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp
index ec8631d..16c7a5d 100644
--- a/SpaceCadetPinball/winmain.cpp
+++ b/SpaceCadetPinball/winmain.cpp
@@ -131,7 +131,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
picce.dwSize = 8;
picce.dwICC = 5885;
InitCommonControlsEx(&picce);
-
+
WNDCLASSA WndClass{};
WndClass.style = 4104;
WndClass.lpfnWndProc = message_handler;
@@ -167,7 +167,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
if (strstr(lpCmdLine, "-fullscreen"))
{
options::Options.FullScreen = 1;
- options::menu_check(0x193u, 1);
+ options::menu_check(Menu1_Full_Screen, 1);
}
ShowWindow(hwnd_frame, nShowCmd);
@@ -331,7 +331,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
{
activated = 0;
fullscrn::activate(0);
- options::menu_check(0x193u, 0);
+ options::menu_check(Menu1_Full_Screen, 0);
options::Options.FullScreen = 0;
SetThreadPriority(GetCurrentThread(), 0);
Sound::Deactivate();
@@ -359,11 +359,11 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
auto voiceCount = options::get_int(nullptr, "Voices", 8);
if (!Sound::Init(hinst, voiceCount, nullptr))
- options::menu_set(0xC9u, 0);
+ options::menu_set(Menu1_Sounds, 0);
Sound::Activate();
if (!pinball::quickFlag && !midi::music_init(hWnd))
- options::menu_set(0xCAu, 0);
+ options::menu_set(Menu1_Music, 0);
if (pb::init())
_exit(0);
@@ -432,7 +432,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
if (fullscrn::displaychange())
{
options::Options.FullScreen = 0;
- options::menu_check(0x193u, 0);
+ options::menu_check(Menu1_Full_Screen, 0);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_KEYUP:
@@ -640,7 +640,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
if (wParam == 4 && options::Options.FullScreen)
{
options::Options.FullScreen = 0;
- options::menu_check(0x193u, 0);
+ options::menu_check(Menu1_Full_Screen, 0);
fullscrn::set_screen_mode(options::Options.FullScreen);
}
return DefWindowProcA(hWnd, Msg, wParam, lParam);