1
0
Fork 0
mirror of https://github.com/k4zmu2a/SpaceCadetPinball.git synced 2024-11-22 17:00:18 +01:00

Fixed timer.

This commit is contained in:
oz 2020-12-06 16:21:56 +03:00
parent 090beefd07
commit b412563ee3
11 changed files with 185 additions and 115 deletions

Binary file not shown.

View file

@ -158,6 +158,7 @@
<ClInclude Include="DatParser.h" /> <ClInclude Include="DatParser.h" />
<ClInclude Include="fullscrn.h" /> <ClInclude Include="fullscrn.h" />
<ClInclude Include="gdrv.h" /> <ClInclude Include="gdrv.h" />
<ClInclude Include="high_score.h" />
<ClInclude Include="loader.h" /> <ClInclude Include="loader.h" />
<ClInclude Include="maths.h" /> <ClInclude Include="maths.h" />
<ClInclude Include="memory.h" /> <ClInclude Include="memory.h" />
@ -219,6 +220,7 @@
<ClCompile Include="DatParser.cpp" /> <ClCompile Include="DatParser.cpp" />
<ClCompile Include="fullscrn.cpp" /> <ClCompile Include="fullscrn.cpp" />
<ClCompile Include="gdrv.cpp" /> <ClCompile Include="gdrv.cpp" />
<ClCompile Include="high_score.cpp" />
<ClCompile Include="loader.cpp" /> <ClCompile Include="loader.cpp" />
<ClCompile Include="maths.cpp" /> <ClCompile Include="maths.cpp" />
<ClCompile Include="memory.cpp" /> <ClCompile Include="memory.cpp" />

View file

@ -210,6 +210,9 @@
<ClInclude Include="TTextBoxMessage.h"> <ClInclude Include="TTextBoxMessage.h">
<Filter>Header Files\TPinballComponent</Filter> <Filter>Header Files\TPinballComponent</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="high_score.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="pch.cpp"> <ClCompile Include="pch.cpp">
@ -386,6 +389,9 @@
<ClCompile Include="TTextBoxMessage.cpp"> <ClCompile Include="TTextBoxMessage.cpp">
<Filter>Source Files\TPinballComponent</Filter> <Filter>Source Files\TPinballComponent</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="high_score.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Natvis Include="NatvisFile.natvis" /> <Natvis Include="NatvisFile.natvis" />

View file

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

View file

@ -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);
};

View file

@ -53,14 +53,14 @@ void options::init(HMENU menuHandle)
Options.LeftTableBumpKey = get_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey); Options.LeftTableBumpKey = get_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey);
Options.RightTableBumpKey = get_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey); Options.RightTableBumpKey = get_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey);
Options.BottomTableBumpKey = get_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey); 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); Sound::Enable(0, 7, Options.Sounds);
menu_check(0xCAu, Options.Music); menu_check(Menu1_Music, Options.Music);
menu_check(0x193u, Options.FullScreen); menu_check(Menu1_Full_Screen, Options.FullScreen);
menu_check(0x198u, Options.Players == 1); menu_check(Menu1_1Player, Options.Players == 1);
menu_check(0x199u, Options.Players == 2); menu_check(Menu1_2Players, Options.Players == 2);
menu_check(0x19Au, Options.Players == 3); menu_check(Menu1_3Players, Options.Players == 3);
menu_check(0x19Bu, Options.Players == 4); menu_check(Menu1_4Players, Options.Players == 4);
auto tmpBuf = memory::allocate(0x1F4u); auto tmpBuf = memory::allocate(0x1F4u);
if (tmpBuf) if (tmpBuf)
{ {
@ -247,10 +247,10 @@ void options::toggle(UINT uIDCheckItem)
if (uIDCheckItem > 407 && uIDCheckItem <= 411) if (uIDCheckItem > 407 && uIDCheckItem <= 411)
{ {
Options.Players = uIDCheckItem - 407; Options.Players = uIDCheckItem - 407;
menu_check(0x198u, Options.Players == 1); menu_check(Menu1_1Player, Options.Players == 1);
menu_check(0x199u, Options.Players == 2); menu_check(Menu1_2Players, Options.Players == 2);
menu_check(0x19Au, Options.Players == 3); menu_check(Menu1_3Players, Options.Players == 3);
menu_check(0x19Bu, Options.Players == 4); menu_check(Menu1_4Players, Options.Players == 4);
} }
} }

View file

@ -1,6 +1,7 @@
#include "pch.h" #include "pch.h"
#include "pb.h" #include "pb.h"
#include "high_score.h"
#include "memory.h" #include "memory.h"
#include "pinball.h" #include "pinball.h"
#include "proj.h" #include "proj.h"
@ -11,12 +12,14 @@
#include "options.h" #include "options.h"
#include "timer.h" #include "timer.h"
#include "winmain.h" #include "winmain.h"
#include "resource.h"
TPinballTable* pb::MainTable = nullptr; TPinballTable* pb::MainTable = nullptr;
datFileStruct* pb::record_table = 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:: 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; float pb::time_now, pb::time_next;
char pb::highscore_table[32];
int pb::init() int pb::init()
{ {
@ -58,8 +61,7 @@ int pb::init()
} }
render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]); render::init(nullptr, zMin, zScaler, tableSize[0], tableSize[1]);
gdrv::fill_bitmap(&render::vscreen, render::vscreen.Width, render::vscreen.Height, 0, 0, gdrv::fill_bitmap(&render::vscreen, render::vscreen.Width, render::vscreen.Height, 0, 0, '\xFF'); // temp
static_cast<char>(0xff)); // temp
gdrv::copy_bitmap( gdrv::copy_bitmap(
&render::vscreen, &render::vscreen,
backgroundBmp->Width, backgroundBmp->Width,
@ -84,7 +86,7 @@ int pb::init()
MainTable = new TPinballTable(); 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); //v11 = *(float*)((char*)MainTable->ListP2.ListPtr->Array[0] + 154);
//ball_speed_limit = v11 * 200.0; //ball_speed_limit = v11 * 200.0;
@ -97,7 +99,7 @@ int pb::uninit()
score::unload_msg_font(); score::unload_msg_font();
loader::unload(); loader::unload();
partman::unload_records(record_table); partman::unload_records(record_table);
//high_score_write(highscore_table, (int)&pb_state); high_score::write(highscore_table, &state);
if (MainTable) if (MainTable)
delete MainTable; delete MainTable;
MainTable = nullptr; MainTable = nullptr;
@ -128,6 +130,52 @@ void pb::paint()
void pb::mode_change(int mode) 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() void pb::toggle_demo()
@ -151,8 +199,8 @@ void pb::replay_level(int demoMode)
{ {
demo_mode = demoMode; demo_mode = demoMode;
mode_change(1); mode_change(1);
//if (options::Options.Music) if (options::Options.Music)
midi::play_pb_theme(0); midi::play_pb_theme(0);
MainTable->Message(1014, static_cast<float>(options::Options.Players)); MainTable->Message(1014, static_cast<float>(options::Options.Players));
} }
@ -388,6 +436,7 @@ int pb::cheat_bump_rank()
void pb::launch_ball() void pb::launch_ball()
{ {
MainTable->Plunger->Message(1017, 0.0f);
} }
int pb::end_game() int pb::end_game()
@ -397,4 +446,5 @@ int pb::end_game()
void pb::high_scores() void pb::high_scores()
{ {
high_score::show_high_score_dialog(highscore_table);
} }

View file

@ -35,4 +35,6 @@ public:
private : private :
static int demo_mode, mode_countdown_; static int demo_mode, mode_countdown_;
static float time_now, time_next; static float time_now, time_next;
static char highscore_table[32];
static int state;
}; };

View file

@ -4,128 +4,124 @@
#include "memory.h" #include "memory.h"
#include "pb.h" #include "pb.h"
timer_struct timer::timerStruct{}; int timer::SetCount;
int timer::set_count; timer_struct* timer::ActiveList;
int timer::MaxCount;
int timer::Count;
timer_struct* timer::FreeList;
timer_struct* timer::TimerBuffer;
int timer::init(int count) int timer::init(int count)
{ {
auto buf = (timer_sub_struct*)memory::allocate(sizeof(timer_sub_struct) * count); auto buf = (timer_struct*)memory::allocate(sizeof(timer_struct) * count);
timerStruct.TimerMem = buf; TimerBuffer = buf;
if (!buf) if (!buf)
return 1; return 1;
timerStruct.Count = 0; Count = 0;
timerStruct.MaxCount = count; MaxCount = count;
set_count = 1; SetCount = 1;
for (int index = 0; index < count - 1; index++) for (int index = 0; index < count - 1; index++)
buf[index].NextTimer = &buf[index + 1]; buf[index].NextTimer = &buf[index + 1];
buf[count - 1].NextTimer = nullptr; buf[count - 1].NextTimer = nullptr;
timerStruct.NextTimer = nullptr; ActiveList = nullptr;
timerStruct.LastTimer = buf; FreeList = buf;
return 0; return 0;
} }
void timer::uninit() void timer::uninit()
{ {
if (timerStruct.TimerMem) if (TimerBuffer)
memory::free(timerStruct.TimerMem); memory::free(TimerBuffer);
timerStruct.TimerMem = nullptr; TimerBuffer = nullptr;
} }
int timer::kill(int timerId) int timer::kill(int timerId)
{ {
timer_sub_struct* next = timerStruct.NextTimer; timer_struct* current = ActiveList;
int index = 0; int index = 0;
timer_sub_struct* current = nullptr; timer_struct* prev = nullptr;
if (timerStruct.Count <= 0) if (Count <= 0)
return 0; return 0;
while (timerId != next->TimerId) while (timerId != current->TimerId)
{ {
++index; ++index;
current = next; prev = current;
next = next->NextTimer; current = current->NextTimer;
if (index >= timerStruct.Count) if (index >= Count)
return 0; return 0;
} }
if (current) if (prev)
current->NextTimer = next->NextTimer; prev->NextTimer = current->NextTimer;
else else
timerStruct.NextTimer = next->NextTimer; ActiveList = current->NextTimer;
--timerStruct.Count; --Count;
next->NextTimer = timerStruct.LastTimer; current->NextTimer = FreeList;
timerStruct.LastTimer = next; FreeList = current;
return timerId; return timerId;
} }
int timer::set(float time, void* caller, void (* callback)(int, void*)) int timer::set(float time, void* caller, void (* callback)(int, void*))
{ {
if (timerStruct.Count >= timerStruct.MaxCount) if (Count >= MaxCount)
return 0; return 0;
/*timerStruct.LastTimer->NextTimer = nullptr; auto timer = FreeList;
timerStruct.LastTimer = timerStruct.LastTimer->NextTimer;*/ FreeList = timer->NextTimer;
timer->NextTimer = nullptr;
auto lastNext = timerStruct.LastTimer->NextTimer; auto prev = ActiveList;
timerStruct.LastTimer->NextTimer = nullptr; auto current = ActiveList;
timerStruct.LastTimer = lastNext;
auto prev = timerStruct.NextTimer;
auto current = timerStruct.NextTimer;
auto targetTime = pb::time_ticks + static_cast<int>(time * 1000.0f); auto targetTime = pb::time_ticks + static_cast<int>(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; prev = current;
current = current->NextTimer; current = current->NextTimer;
} }
auto last = timerStruct.LastTimer;
if (current != prev) if (current != prev)
{ {
timerStruct.LastTimer->NextTimer = prev->NextTimer; timer->NextTimer = prev->NextTimer;
prev->NextTimer = last; prev->NextTimer = timer;
} }
else else
{ {
timerStruct.LastTimer->NextTimer = timerStruct.NextTimer; timer->NextTimer = ActiveList;
timerStruct.NextTimer = last; ActiveList = timer;
} }
last->Caller = caller; timer->Caller = caller;
last->Callback = callback; timer->Callback = callback;
last->TimerId = set_count; timer->TimerId = SetCount;
last->TargetTime = targetTime; timer->TargetTime = targetTime;
timerStruct.Count++; Count++;
set_count++; SetCount++;
if (set_count <= 0) if (SetCount <= 0)
set_count = 1; SetCount = 1;
return last->TimerId; return timer->TimerId;
} }
int timer::check() int timer::check()
{ {
timer_sub_struct curCopy{}; timer_struct* current = ActiveList;
timer_sub_struct* current = timerStruct.NextTimer;
int index = 0; int index = 0;
if (timerStruct.NextTimer) if (ActiveList)
{ {
while (pb::time_ticks >= current->TargetTime) while (pb::time_ticks >= current->TargetTime)
{ {
--timerStruct.Count; --Count;
memcpy(&curCopy, current, sizeof curCopy); // Advance active list, move current to free
timer_sub_struct** nextPtr = &current->NextTimer; ActiveList = current->NextTimer;
current = current->NextTimer; current->NextTimer = FreeList;
timerStruct.NextTimer = current; FreeList = current;
*nextPtr = timerStruct.LastTimer; if (current->Callback != nullptr)
timerStruct.LastTimer = current; current->Callback(current->TimerId, current->Caller);
if (curCopy.Callback != nullptr)
{ current = ActiveList;
curCopy.Callback(curCopy.TimerId, curCopy.Caller);
current = timerStruct.NextTimer;
}
++index; ++index;
if (index > 1) if (index > 1)
break; break;
@ -134,18 +130,14 @@ int timer::check()
} }
while (current && pb::time_ticks >= current->TargetTime + 100) while (current && pb::time_ticks >= current->TargetTime + 100)
{ {
--timerStruct.Count; --Count;
memcpy(&curCopy, current, sizeof curCopy); ActiveList = current->NextTimer;
timer_sub_struct** nextPtr = &current->NextTimer; current->NextTimer = FreeList;
current = current->NextTimer; FreeList = current;
timerStruct.NextTimer = current; if (current->Callback != nullptr)
*nextPtr = timerStruct.LastTimer; current->Callback(current->TimerId, current->Caller);
timerStruct.LastTimer = current;
if (curCopy.Callback != nullptr) current = ActiveList;
{
curCopy.Callback(curCopy.TimerId, curCopy.Caller);
current = timerStruct.NextTimer;
}
++index; ++index;
} }
} }

View file

@ -1,24 +1,14 @@
#pragma once #pragma once
struct __declspec(align(4)) timer_sub_struct struct __declspec(align(4)) timer_struct
{ {
int TargetTime; int TargetTime;
void* Caller; void* Caller;
void (* Callback)(int, void*); void (* Callback)(int, void*);
timer_sub_struct* NextTimer; timer_struct* NextTimer;
int TimerId; 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 class timer
{ {
public: public:
@ -29,6 +19,10 @@ public:
static int check(); static int check();
private: private:
static timer_struct timerStruct; static int SetCount;
static int set_count; static timer_struct* ActiveList;
static int MaxCount;
static int Count;
static timer_struct* FreeList;
static timer_struct* TimerBuffer;
}; };

View file

@ -131,7 +131,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
picce.dwSize = 8; picce.dwSize = 8;
picce.dwICC = 5885; picce.dwICC = 5885;
InitCommonControlsEx(&picce); InitCommonControlsEx(&picce);
WNDCLASSA WndClass{}; WNDCLASSA WndClass{};
WndClass.style = 4104; WndClass.style = 4104;
WndClass.lpfnWndProc = message_handler; WndClass.lpfnWndProc = message_handler;
@ -167,7 +167,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
if (strstr(lpCmdLine, "-fullscreen")) if (strstr(lpCmdLine, "-fullscreen"))
{ {
options::Options.FullScreen = 1; options::Options.FullScreen = 1;
options::menu_check(0x193u, 1); options::menu_check(Menu1_Full_Screen, 1);
} }
ShowWindow(hwnd_frame, nShowCmd); ShowWindow(hwnd_frame, nShowCmd);
@ -331,7 +331,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
{ {
activated = 0; activated = 0;
fullscrn::activate(0); fullscrn::activate(0);
options::menu_check(0x193u, 0); options::menu_check(Menu1_Full_Screen, 0);
options::Options.FullScreen = 0; options::Options.FullScreen = 0;
SetThreadPriority(GetCurrentThread(), 0); SetThreadPriority(GetCurrentThread(), 0);
Sound::Deactivate(); 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); auto voiceCount = options::get_int(nullptr, "Voices", 8);
if (!Sound::Init(hinst, voiceCount, nullptr)) if (!Sound::Init(hinst, voiceCount, nullptr))
options::menu_set(0xC9u, 0); options::menu_set(Menu1_Sounds, 0);
Sound::Activate(); Sound::Activate();
if (!pinball::quickFlag && !midi::music_init(hWnd)) if (!pinball::quickFlag && !midi::music_init(hWnd))
options::menu_set(0xCAu, 0); options::menu_set(Menu1_Music, 0);
if (pb::init()) if (pb::init())
_exit(0); _exit(0);
@ -432,7 +432,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
if (fullscrn::displaychange()) if (fullscrn::displaychange())
{ {
options::Options.FullScreen = 0; options::Options.FullScreen = 0;
options::menu_check(0x193u, 0); options::menu_check(Menu1_Full_Screen, 0);
} }
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_KEYUP: 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) if (wParam == 4 && options::Options.FullScreen)
{ {
options::Options.FullScreen = 0; options::Options.FullScreen = 0;
options::menu_check(0x193u, 0); options::menu_check(Menu1_Full_Screen, 0);
fullscrn::set_screen_mode(options::Options.FullScreen); fullscrn::set_screen_mode(options::Options.FullScreen);
} }
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);