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

View File

@ -210,6 +210,9 @@
<ClInclude Include="TTextBoxMessage.h">
<Filter>Header Files\TPinballComponent</Filter>
</ClInclude>
<ClInclude Include="high_score.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
@ -386,6 +389,9 @@
<ClCompile Include="TTextBoxMessage.cpp">
<Filter>Source Files\TPinballComponent</Filter>
</ClCompile>
<ClCompile Include="high_score.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<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.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);
}
}

View File

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

View File

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

View File

@ -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<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;
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 = &current->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 = &current->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;
}
}

View File

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

View File

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