diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 7be464b..2de37c2 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/SpaceCadetPinball.rc b/SpaceCadetPinball/SpaceCadetPinball.rc index 50d6d33..f6e1dca 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.rc +++ b/SpaceCadetPinball/SpaceCadetPinball.rc @@ -113,7 +113,219 @@ PBMSG_FT RCDATA "PB_MSGFT.bin" // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -ICON_1 ICON "icon_1.ico" +ICON_1 ICON "icon_1.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +DIALOG_1 DIALOG 18, 18, 157, 78 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION +CAPTION "About" +BEGIN + CTEXT "3D-Pinball for Windows",-1,11,6,135,8 + CTEXT "Version 1.0",-1,40,37,76,8 + ICON "ICON_1",-1,69,18,16,16 + DEFPUSHBUTTON "Ok",1,66,60,24,12 +END + +DLG_HIGHSCORES DIALOGEX 20, 22, 274, 141 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "High Scores" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + DEFPUSHBUTTON "OK",DLG_HIGHSCORES_Ok,109,120,50,14 + PUSHBUTTON "Cancel",DLG_HIGHSCORES_Cancel,163,120,50,14 + PUSHBUTTON "&Clear",DLG_HIGHSCORES_Clear,217,120,50,14 + LTEXT "Name",701,49,7,24,8 + LTEXT "Score",702,200,7,20,8 + LTEXT "Rank",703,13,7,20,8 + RTEXT "1",704,13,31,16,12 + RTEXT "2",705,13,47,16,12 + RTEXT "3",706,13,63,16,12 + RTEXT "4",707,13,79,16,12 + RTEXT "5",708,13,95,16,12 + LTEXT "",DLG_HIGHSCORES_StaticName1,49,31,120,12 + LTEXT "",DLG_HIGHSCORES_StaticName2,49,47,120,12 + LTEXT "",DLG_HIGHSCORES_StaticName3,49,63,120,12 + LTEXT "",DLG_HIGHSCORES_StaticName4,49,79,120,12 + LTEXT "",DLG_HIGHSCORES_StaticName5,49,95,120,12 + RTEXT "",DLG_HIGHSCORES_Score1,180,31,58,12 + RTEXT "",DLG_HIGHSCORES_Score2,180,47,58,12 + RTEXT "",DLG_HIGHSCORES_Score3,180,63,58,12 + RTEXT "",DLG_HIGHSCORES_Score4,180,79,58,12 + RTEXT "",DLG_HIGHSCORES_Score5,180,95,58,12 + EDITTEXT DLG_HIGHSCORES_EditName1,47,29,120,12,WS_DISABLED + EDITTEXT DLG_HIGHSCORES_EditName2,47,45,120,12,WS_DISABLED + EDITTEXT DLG_HIGHSCORES_EditName3,47,61,120,12,WS_DISABLED + EDITTEXT DLG_HIGHSCORES_EditName4,47,77,120,12,WS_DISABLED + EDITTEXT DLG_HIGHSCORES_EditName5,47,93,120,12,WS_DISABLED + CONTROL "",606,"Static",SS_BLACKFRAME,7,21,259,92 +END + +EDIT_COMPONENTS DIALOG 0, 0, 312, 94 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU +CAPTION "Edit Pinball Components FOR TESTING ONLY" +BEGIN + LISTBOX 100,1,12,68,79,LBS_SORT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",1,81,75,41,14 + GROUPBOX "",103,136,0,175,93 + EDITTEXT 130,141,10,34,12 + EDITTEXT 131,141,23,34,12 + EDITTEXT 132,141,36,34,12 + EDITTEXT 133,141,49,34,12 + EDITTEXT 134,141,62,34,12 + EDITTEXT 135,141,75,34,12 + LTEXT "Text",136,178,12,130,8 + LTEXT "Text",137,178,25,130,8 + LTEXT "Text",138,178,38,130,8 + LTEXT "Text",139,178,51,130,8 + LTEXT "Text",140,178,64,130,8 + LTEXT "Text",141,178,77,130,8 + EDITTEXT 149,142,10,38,12 + EDITTEXT 150,142,23,38,12 + EDITTEXT 151,142,36,38,12 + EDITTEXT 152,142,49,38,12 + EDITTEXT 153,142,62,38,12 + EDITTEXT 154,142,75,38,12 + LTEXT "1",156,184,12,120,8 + LTEXT "2",157,184,25,120,8 + LTEXT "3",158,184,38,120,8 + LTEXT "4",159,184,51,120,8 + LTEXT "5",160,184,64,120,8 + LTEXT "6",161,184,77,120,8 + PUSHBUTTON "Reset",163,81,56,41,12 + LTEXT "Text",164,146,26,162,8 + LTEXT "Text",165,146,54,162,8 + LTEXT "Text",166,146,81,162,8 + PUSHBUTTON "Change...",167,245,10,62,14 + PUSHBUTTON "Change...",168,245,38,62,14 + PUSHBUTTON "Change...",169,245,65,62,14 + CONTROL "Sound Effects",170,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,74,10,58,10 + CONTROL "Physics",171,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,73,24,59,10 + CONTROL "Scoring",172,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,73,38,40,10 + LTEXT "Text",173,146,13,97,8 + LTEXT "Text",174,146,41,97,8 + LTEXT "Text",175,146,68,97,8 + LTEXT "Components:",176,2,3,43,8 +END + +KEYMAPPER DIALOG 2, 9, 284, 183 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU +CAPTION "3D Pinball: Player Controls" +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "OK",1,119,163,50,14 + PUSHBUTTON "Cancel",2,173,163,50,14 + PUSHBUTTON "&Default",501,227,163,50,14 + LTEXT "&Left Flipper",901,20,87,39,10 + COMBOBOX 401,66,85,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Right &Flipper",902,146,87,44,10 + COMBOBOX 402,192,85,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Left &Table Bump",904,20,107,34,17 + COMBOBOX 404,66,108,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&Right Table Bump",905,146,107,38,19 + COMBOBOX 405,192,108,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&BottomTable Bump",906,20,131,41,18 + COMBOBOX 406,66,133,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "&Plunger",903,146,136,39,8 + COMBOBOX 403,192,133,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "To change game controls, choose the control options you want, click the Arrow buttons to change specific keys, and then choose OK.",801,14,17,249,18 + LTEXT "To restore 3D Pinball to its original settings, choose Default, and then choose OK. To use the Arrow keys on the numeric keypad, make sure NUMLOCK is off.",802,14,38,256,25 + GROUPBOX "Control Options",908,7,71,269,87 + GROUPBOX "Instructions",909,7,5,269,61 +END + +XXDLG_HIGHSCORES DIALOG 20, 22, 211, 116 +STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "High Scores" +BEGIN + DEFPUSHBUTTON "OK",1,32,97,33,14,BS_LEFTTEXT + PUSHBUTTON "Cancel",2,89,97,33,14 + PUSHBUTTON "&Clear",112,146,97,33,14 + LTEXT "Name",-1,51,8,24,8 + LTEXT "Score",-1,160,8,20,8 + LTEXT "Rank",-1,15,8,20,8 + RTEXT "1",-1,15,28,16,12 + RTEXT "2",-1,15,40,16,12 + RTEXT "3",-1,15,52,16,12 + RTEXT "4",-1,15,64,16,12 + RTEXT "5",-1,15,76,16,12 + LTEXT "",401,51,28,88,12 + LTEXT "",402,51,40,88,12 + LTEXT "",403,51,52,88,12 + LTEXT "",404,51,64,88,12 + LTEXT "",405,51,76,88,12 + RTEXT "",501,140,28,58,12 + RTEXT "",502,140,40,58,12 + RTEXT "",503,140,52,58,12 + RTEXT "",504,140,64,58,12 + RTEXT "",505,140,76,58,12 + EDITTEXT 601,49,26,88,12,WS_DISABLED + EDITTEXT 602,49,38,88,12,WS_DISABLED + EDITTEXT 603,49,50,88,12,WS_DISABLED + EDITTEXT 604,49,62,88,12,WS_DISABLED + EDITTEXT 605,49,74,88,12,WS_DISABLED + CONTROL "",-1,"Static",SS_BLACKFRAME,9,22,195,69 +END + +XXKEYMAPPER DIALOG 2, 9, 277, 158 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTEXTHELP | WS_POPUP | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU +CAPTION "3D Pinball: Player Controls" +FONT 8, "MS Shell Dlg" +BEGIN + PUSHBUTTON "OK",1,221,84,50,14 + PUSHBUTTON "Cancel",2,221,105,50,14 + PUSHBUTTON "Default",501,221,127,50,14 + COMBOBOX 401,50,82,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX 402,157,82,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX 404,50,105,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX 405,157,105,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX 406,50,130,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX 403,157,130,53,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Plunger",811,114,133,39,8 + RTEXT "Right Flipper",807,107,84,46,10 + CTEXT "Left Table Bump",912,12,102,34,19 + CTEXT "Right Table Bump",914,115,102,38,19 + LTEXT "To change game controls, choose the control options you want, click the Arrow buttons to change specific keys, and then choose OK.",801,12,13,249,18 + LTEXT "To restore 3D Pinball to its original settings, choose Default, and then choose OK. To use the Arrow keys on the numeric keypad, make sure NUMLOCK is off.",802,12,32,256,25 + GROUPBOX "Control Options",908,5,67,214,87 + RTEXT "Left Flipper",803,9,84,39,10 + GROUPBOX "Instructions",909,5,1,265,61 + CTEXT "BottomTable Bump",916,7,127,41,19 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + "DIALOG_1", DIALOG + BEGIN + END + + "DLG_HIGHSCORES", DIALOG + BEGIN + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// AFX_DIALOG_LAYOUT +// + +DLG_HIGHSCORES AFX_DIALOG_LAYOUT +BEGIN + 0 +END ///////////////////////////////////////////////////////////////////////////// diff --git a/SpaceCadetPinball/high_score.cpp b/SpaceCadetPinball/high_score.cpp index e00ab80..411fa6b 100644 --- a/SpaceCadetPinball/high_score.cpp +++ b/SpaceCadetPinball/high_score.cpp @@ -1,16 +1,306 @@ #include "pch.h" #include "high_score.h" -int high_score::read(CHAR* table, int* ptrToSmth) +#include "fullscrn.h" +#include "memory.h" +#include "options.h" +#include "pinball.h" +#include "resource.h" +#include "winmain.h" + +int high_score::dlg_enter_name; +int high_score::dlg_score; +int high_score::position; +LPCSTR high_score::default_name; +high_score_struct* high_score::dlg_hst; + +winhelp_entry high_score::winHelpArgs[21] { + winhelp_entry{0x70, 0x3E9}, + winhelp_entry{0x191, 0x3EB}, + winhelp_entry{0x1F5, 0x3EB}, + winhelp_entry{0x259, 0x3EB}, + winhelp_entry{0x192, 0x3EB}, + winhelp_entry{0x193, 0x3EB}, + winhelp_entry{0x194, 0x3EB}, + winhelp_entry{0x195, 0x3EB}, + winhelp_entry{0x1F6, 0x3EB}, + winhelp_entry{0x1F7, 0x3EB}, + winhelp_entry{0x1F8, 0x3EB}, + winhelp_entry{0x1F9, 0x3EB}, + winhelp_entry{0x2BD, 0x3EB}, + winhelp_entry{0x2BE, 0x3EB}, + winhelp_entry{0x2BF, 0x3EB}, + winhelp_entry{0x2C0, 0x3EB}, + winhelp_entry{0x2C1, 0x3EB}, + winhelp_entry{0x2C2, 0x3EB}, + winhelp_entry{0x2C3, 0x3EB}, + winhelp_entry{0x2C4, 0x3EB}, + winhelp_entry{0, 0}, +}; + +int high_score::read(high_score_struct* table, int* ptrToSmth) +{ + char Buffer[20]; + + int scoreSum = 0; + clear_table(table); + char* buf1 = memory::allocate(300u); + if (!buf1) + return 1; + char* buf2 = memory::allocate(300u); + int position = 0; + high_score_struct* tablePtr = table; + const CHAR* optPath = pinball::get_rc_string(166, 0); + do + { + _itoa_s(position, Buffer, 10); + lstrcatA(Buffer, ".Name"); + options::get_string(optPath, Buffer, buf1, pinball::WindowName, 32); + buf1[32] = 0; + lstrcpyA(tablePtr->Name, buf1); + _itoa_s(position, Buffer, 10); + lstrcatA(Buffer, ".Score"); + options::get_string(optPath, Buffer, buf1, pinball::WindowName, 300); + tablePtr->Score = atol(buf1); + for (int i = lstrlenA(tablePtr->Name); --i >= 0; scoreSum += tablePtr->Name[i]) + { + } + scoreSum += tablePtr->Score; + ++position; + ++tablePtr; + } + while (position < 5); + scramble_number_string(scoreSum, buf1); + options::get_string(optPath, "Verification", buf2, pinball::WindowName, 300); + if (lstrcmpA(buf1, buf2)) + clear_table(table); + memory::free(buf1); + memory::free(buf2); return 0; } -int high_score::write(CHAR* table, int* ptrToSmth) +int high_score::write(high_score_struct* table, int* ptrToSmth) { + char Buffer[20]; + + high_score_struct* tablePtr = table; + int scoreSum = 0; + CHAR* buf = memory::allocate(300u); + if (!buf) + return 1; + int position = 0; + const CHAR* optPath = pinball::get_rc_string(166, 0); + do + { + _itoa_s(position, Buffer, 10); + lstrcatA(Buffer, ".Name"); + options::set_string(optPath, Buffer, tablePtr->Name); + _itoa_s(position, Buffer, 10); + lstrcatA(Buffer, ".Score"); + _ltoa_s(tablePtr->Score, buf, 300, 10); + options::set_string(optPath, Buffer, buf); + for (int i = lstrlenA(tablePtr->Name); --i >= 0; scoreSum += tablePtr->Name[i]) + { + } + scoreSum += tablePtr->Score; + ++position; + ++tablePtr; + } + while (position < 5); + scramble_number_string(scoreSum, buf); + options::set_string(optPath, "Verification", buf); + memory::free(buf); return 0; } -void high_score::show_high_score_dialog(CHAR* table) +void high_score::clear_table(high_score_struct* table) { + for (int index = 5; index; --index) + { + table->Score = -999; + table->Name[0] = 0; + ++table; + } +} + +int high_score::get_score_position(high_score_struct* table, int score) +{ + if (score <= 0) + return -1; + + for (int position = 0; position < 5; position++) + { + if (table[position].Score < score) + return position; + } + return -1; +} + +int high_score::place_new_score_into(high_score_struct* table, int score, LPSTR scoreStr, int position) +{ + if (position >= 0) + { + if (position <= 4) + { + high_score_struct* tablePtr = table + 4; + int index = 5 - position; + do + { + --index; + memcpy(tablePtr, &tablePtr[-1], sizeof(high_score_struct)); + --tablePtr; + } + while (index); + } + high_score_struct* posTable = &table[position]; + posTable->Score = score; + if (lstrlenA(scoreStr) >= 31) + scoreStr[31] = 0; + lstrcpyA(posTable->Name, scoreStr); + posTable->Name[31] = 0; + } + return position; +} + +void high_score::scramble_number_string(int Value, char* Buffer) +{ + _ltoa_s(Value, Buffer, 300, 10); +} + +void high_score::show_high_score_dialog(high_score_struct* table) +{ + dlg_enter_name = 0; + dlg_score = 0; + dlg_hst = table; + DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0); +} + +void high_score::show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName) +{ + position = pos; + dlg_score = score; + dlg_hst = table; + dlg_enter_name = 1; + default_name = defaultName; + while (DialogBoxParamA(winmain::hinst, "dlg_highscores", winmain::hwnd_frame, HighScore, 0)) + { + } +} + +INT_PTR __stdcall high_score::HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + HWND parent; + int nIDDlgItem; + CHAR String1[256]; + CHAR name[32]; + + switch (msg) + { + case WM_CLOSE: + SendMessageA(hWnd, WM_COMMAND, WM_DESTROY, 0); + break; + case WM_HELP: + WinHelpA(*(HWND*)(lParam + 12), "pinball.hlp", HELP_WM_HELP, (ULONG_PTR)winHelpArgs); + break; + case WM_CONTEXTMENU: + WinHelpA((HWND)wParam, "pinball.hlp", HELP_CONTEXTMENU, (ULONG_PTR)winHelpArgs); + break; + case WM_INITDIALOG: + show_high_scores(hWnd, dlg_hst); + for (nIDDlgItem = DLG_HIGHSCORES_EditName1; nIDDlgItem < 611; ++nIDDlgItem) + { + ShowWindow(GetDlgItem(hWnd, nIDDlgItem), 0); + } + if (dlg_enter_name == 1) + { + if (position == -1) + { + dlg_enter_name = 0; + return 1; + } + HWND nameTextBox = GetDlgItem(hWnd, position + DLG_HIGHSCORES_EditName1); + ShowWindow(nameTextBox, 5); + EnableWindow(nameTextBox, 1); + SetFocus(nameTextBox); + if (default_name) + { + SetWindowTextA(nameTextBox, default_name); + SendMessageA(nameTextBox, EM_SETSEL, 0, -1); + } + SendMessageA(nameTextBox, EM_SETLIMITTEXT, 31u, 0); + } + else + { + SetFocus(hWnd); + } + parent = GetParent(hWnd); + if (parent) + fullscrn::center_in(parent, hWnd); + return 0; + case WM_COMMAND: + switch (wParam) + { + case DLG_HIGHSCORES_Ok: + if (dlg_enter_name != 1) + { + break; + } + GetDlgItemTextA(hWnd, position + DLG_HIGHSCORES_EditName1, name, 32); + name[31] = 0; + place_new_score_into(dlg_hst, dlg_score, name, position); + break; + case DLG_HIGHSCORES_Cancel: + break; + case DLG_HIGHSCORES_Clear: + lstrcpyA(String1, pinball::get_rc_string(41, 0)); + if (MessageBoxA(hWnd, pinball::get_rc_string(40, 0), String1, MB_DEFBUTTON2 | MB_OKCANCEL) == 1) + { + clear_table(dlg_hst); + if (dlg_enter_name) + EndDialog(hWnd, 1); + else + EndDialog(hWnd, 0); + } + return 0; + default: + return 0; + } + + dlg_enter_name = 0; + EndDialog(hWnd, 0); + return 1; + } + return 0; +} + + +void high_score::show_high_scores(HWND hDlg, high_score_struct* table) +{ + high_score_struct* tablePtr = table; + int nextPosition = 0; + for (int i = 0; i < 5; ++i) + { + if (dlg_enter_name == 1 && position == i) + { + hsdlg_show_score(hDlg, " ", dlg_score, i); + nextPosition = 1; + } + hsdlg_show_score(hDlg, tablePtr->Name, tablePtr->Score, i + nextPosition); + ++tablePtr; + } +} + +void high_score::hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int position) +{ + CHAR scoreStr[36]; + if (position < 5) + { + score::string_format(score, scoreStr); + if (scoreStr[0]) + { + SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_StaticName1), name); + SetWindowTextA(GetDlgItem(hDlg, position + DLG_HIGHSCORES_Score1), scoreStr); + } + } } diff --git a/SpaceCadetPinball/high_score.h b/SpaceCadetPinball/high_score.h index 667905a..8e80592 100644 --- a/SpaceCadetPinball/high_score.h +++ b/SpaceCadetPinball/high_score.h @@ -1,8 +1,38 @@ #pragma once + +struct high_score_struct +{ + char Name[32]; + int Score; +}; + +struct winhelp_entry +{ + int ControlId; + int ContextId; +}; + + 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); + static int read(high_score_struct* table, int* ptrToSmth); + static int write(high_score_struct* table, int* ptrToSmth); + static void clear_table(high_score_struct* table); + static int get_score_position(high_score_struct* table, int score); + static int place_new_score_into(high_score_struct* table, int score, LPSTR scoreStr, int position); + static void scramble_number_string(int Value, char* Buffer); + + static void show_high_score_dialog(high_score_struct* table); + static void show_and_set_high_score_dialog(high_score_struct* table, int score, int pos, LPCSTR defaultName); + static INT_PTR __stdcall HighScore(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + static void show_high_scores(HWND hDlg, high_score_struct* table); + static void hsdlg_show_score(HWND hDlg, LPCSTR name, int score, int position); +private : + static int dlg_enter_name; + static int dlg_score; + static int position; + static LPCSTR default_name; + static high_score_struct* dlg_hst; + static winhelp_entry winHelpArgs[21]; }; diff --git a/SpaceCadetPinball/pb.cpp b/SpaceCadetPinball/pb.cpp index 047d077..4fa0d1b 100644 --- a/SpaceCadetPinball/pb.cpp +++ b/SpaceCadetPinball/pb.cpp @@ -19,7 +19,7 @@ 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, pb::state; float pb::time_now, pb::time_next; -char pb::highscore_table[32]; +high_score_struct pb::highscore_table[5]; int pb::init() { diff --git a/SpaceCadetPinball/pb.h b/SpaceCadetPinball/pb.h index 18bc3f2..e2fe988 100644 --- a/SpaceCadetPinball/pb.h +++ b/SpaceCadetPinball/pb.h @@ -1,4 +1,5 @@ #pragma once +#include "high_score.h" #include "partman.h" #include "TPinballTable.h" @@ -35,6 +36,6 @@ public: private : static int demo_mode, mode_countdown_; static float time_now, time_next; - static char highscore_table[32]; + static high_score_struct highscore_table[5]; static int state; }; diff --git a/SpaceCadetPinball/resource.h b/SpaceCadetPinball/resource.h index 8cb7725..4f7adb8 100644 --- a/SpaceCadetPinball/resource.h +++ b/SpaceCadetPinball/resource.h @@ -4,7 +4,9 @@ // #define IDS_STRING101 0 #define IDS_STRING102 1 +#define DLG_HIGHSCORES_Ok 1 #define IDS_STRING103 2 +#define DLG_HIGHSCORES_Cancel 2 #define IDS_STRING104 3 #define IDS_STRING105 4 #define IDS_STRING106 5 @@ -119,6 +121,7 @@ #define IDS_STRING211 110 #define IDS_STRING212 111 #define IDS_STRING213 112 +#define DLG_HIGHSCORES_Clear 112 #define IDS_STRING214 113 #define IDS_STRING215 114 #define IDS_STRING216 115 @@ -199,22 +202,36 @@ #define Menu1_Music 202 #define Menu1_Help_Topics 301 #define Menu1_Launch_Ball 401 +#define DLG_HIGHSCORES_StaticName1 401 #define Menu1_Pause_Resume_Game 402 +#define DLG_HIGHSCORES_StaticName2 402 #define Menu1_Full_Screen 403 +#define DLG_HIGHSCORES_StaticName3 403 #define Menu1_Demo 404 +#define DLG_HIGHSCORES_StaticName4 404 #define Menu1_Select_Table 405 +#define DLG_HIGHSCORES_StaticName5 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 +#define DLG_HIGHSCORES_Score1 501 +#define DLG_HIGHSCORES_Score2 502 +#define DLG_HIGHSCORES_Score3 503 +#define DLG_HIGHSCORES_Score4 504 +#define DLG_HIGHSCORES_Score5 505 +#define DLG_HIGHSCORES_EditName1 601 +#define DLG_HIGHSCORES_EditName2 602 +#define DLG_HIGHSCORES_EditName3 603 +#define DLG_HIGHSCORES_EditName4 604 +#define DLG_HIGHSCORES_EditName5 605 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 201 +#define _APS_NEXT_RESOURCE_VALUE 203 #define _APS_NEXT_COMMAND_VALUE 40004 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/SpaceCadetPinball/score.cpp b/SpaceCadetPinball/score.cpp index dd037c8..7119923 100644 --- a/SpaceCadetPinball/score.cpp +++ b/SpaceCadetPinball/score.cpp @@ -3,6 +3,7 @@ #include "loader.h" #include "memory.h" #include "partman.h" +#include "TDrain.h" #include "winmain.h" score_msg_font_type* score::msg_fontp; @@ -17,7 +18,7 @@ scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp) scoreStruct* score = (scoreStruct*)memory::allocate(sizeof(scoreStruct)); if (!score) return nullptr; - score->Unknown1 = -9999; + score->Score = -9999; score->BackgroundBmp = renderBgBmp; __int16* shortArr = (__int16*)partman::field_labeled(loader::loader_table, fieldName, datFieldTypes::ShortArray); if (!shortArr) @@ -26,20 +27,17 @@ scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp) return nullptr; } int groupIndex = *shortArr++; - score->Short1 = *shortArr++; - score->Short2 = *shortArr++; - score->Short3 = *shortArr++; - score->Short4 = *shortArr; - char** bmpPtr = &score->Bitmap8Bit1; - int index = 10; - do + score->OffsetX = *shortArr++; + score->OffsetY = *shortArr++; + score->Width = *shortArr++; + score->Height = *shortArr; + + for (int index = 0; index < 10; index++) { - *bmpPtr = partman::field(loader::loader_table, groupIndex, datFieldTypes::Bitmap8bit); - ++bmpPtr; + score->CharBmp[index] = reinterpret_cast(partman::field( + loader::loader_table, groupIndex, datFieldTypes::Bitmap8bit)); ++groupIndex; - --index; } - while (index); return score; } @@ -150,3 +148,141 @@ void score::unload_msg_font() msg_fontp = nullptr; } } + +void score::erase(scoreStruct* score, int blitFlag) +{ + if (score) + { + if (score->BackgroundBmp) + gdrv::copy_bitmap( + &render::vscreen, + score->Width, + score->Height, + score->OffsetX, + score->OffsetY, + score->BackgroundBmp, + score->OffsetX, + score->OffsetY); + else + gdrv::fill_bitmap(&render::vscreen, score->Width, score->Height, score->OffsetX, score->OffsetY, 0); + if (blitFlag) + gdrv::blit( + &render::vscreen, + score->OffsetX, + score->OffsetY, + score->OffsetX + render::vscreen.XPosition, + score->OffsetY + render::vscreen.YPosition, + score->Width, + score->Height); + } +} + +void score::set(scoreStruct* score, int value) +{ + if (score) + { + score->Score = value; + score->DirtyFlag = true; + } +} + + +void score::update(scoreStruct* score) +{ + char scoreBuf[12]; + if (score && score->DirtyFlag && score->Score <= 1000000000) + { + score->DirtyFlag = false; + int x = score->Width + score->OffsetX; + int y = score->OffsetY; + erase(score, 0); + if (score->Score >= 0) + { + _ltoa_s(score->Score, scoreBuf, 10); + int len = strlen(scoreBuf); + for (int index = len - 1; index >= 0; index--) + { + unsigned char curChar = scoreBuf[index]; + curChar -= '0'; + gdrv_bitmap8* bmp = score->CharBmp[curChar]; + x -= bmp->Width; + int height = bmp->Height; + int width = bmp->Width; + if (render::background_bitmap) + gdrv::copy_bitmap_w_transparency(&render::vscreen, width, height, x, y, bmp, 0, 0); + else + gdrv::copy_bitmap(&render::vscreen, width, height, x, y, bmp, 0, 0); + } + } + gdrv::blit( + &render::vscreen, + score->OffsetX, + score->OffsetY, + score->OffsetX + render::vscreen.XPosition, + score->OffsetY + render::vscreen.YPosition, + score->Width, + score->Height); + } +} + +void score::string_format(int score, char* str) +{ + CHAR separator[12]; + + if (score == -999) + { + *str = 0; + } + else + { + lstrcpyA(separator, ","); + + HKEY phkResult; + DWORD dwDisposition; + if (!RegCreateKeyExA( + HKEY_CURRENT_USER, + "Control Panel\\International", + 0, + nullptr, + 0, + KEY_ALL_ACCESS, + nullptr, + &phkResult, + &dwDisposition)) + { + DWORD cbData = 10; + RegQueryValueExA(phkResult, "sThousand", nullptr, nullptr, (LPBYTE)separator, &cbData); + RegCloseKey(phkResult); + } + int scoreMillions = score % 1000000000 / 1000000; + if (score / 1000000000 <= 0) + { + if (static_cast(scoreMillions) <= 0) + { + if (score % 1000000 / 1000 <= 0) + sprintf_s(str, 36, "%ld", score); + else + sprintf_s(str, 36, "%ld%s%03ld", score % 1000000 / 1000, separator, score % 1000); + } + else + { + sprintf_s(str, 36, "%ld%s%03ld%s%03ld", scoreMillions, separator, score % 1000000 / 1000, separator, + score % 1000); + } + } + else + { + sprintf_s( + str, + 36, + "%ld%s%03ld%s%03ld%s%03ld", + score / 1000000000, + separator, + scoreMillions, + separator, + score % 1000000 / 1000, + separator, + score % 1000); + } + } +} diff --git a/SpaceCadetPinball/score.h b/SpaceCadetPinball/score.h index 7790e1f..83212f9 100644 --- a/SpaceCadetPinball/score.h +++ b/SpaceCadetPinball/score.h @@ -3,23 +3,14 @@ struct scoreStruct { - int Unknown1; - int Unknown2; + int Score; + bool DirtyFlag; gdrv_bitmap8* BackgroundBmp; - int Short1; - int Short2; - int Short3; - int Short4; - char* Bitmap8Bit1; - char* Bitmap8Bit2; - char* Bitmap8Bit3; - char* Bitmap8Bit4; - char* Bitmap8Bit5; - char* Bitmap8Bit6; - char* Bitmap8Bit7; - char* Bitmap8Bit8; - char* Bitmap8Bit9; - char* Bitmap8Bit10; + int OffsetX; + int OffsetY; + int Width; + int Height; + gdrv_bitmap8* CharBmp[10]; }; struct score_msg_font_type @@ -47,4 +38,8 @@ public: static scoreStruct* dup(scoreStruct* score, int scoreIndex); static void load_msg_font(LPCSTR lpName); static void unload_msg_font(); + static void erase(scoreStruct* score, int blitFlag); + static void set(scoreStruct* score, int value); + static void update(scoreStruct* score); + static void string_format(int score, char* str); };