diff --git a/Doc/FuncStats.xlsx b/Doc/FuncStats.xlsx index 05242d5..7be464b 100644 Binary files a/Doc/FuncStats.xlsx and b/Doc/FuncStats.xlsx differ diff --git a/SpaceCadetPinball/Icon_1.ico b/SpaceCadetPinball/Icon_1.ico new file mode 100644 index 0000000..d679d38 Binary files /dev/null and b/SpaceCadetPinball/Icon_1.ico differ diff --git a/SpaceCadetPinball/PB_MSGFT.bin b/SpaceCadetPinball/PB_MSGFT.bin new file mode 100644 index 0000000..4f191f1 Binary files /dev/null and b/SpaceCadetPinball/PB_MSGFT.bin differ diff --git a/SpaceCadetPinball/SpaceCadetPinball.cpp b/SpaceCadetPinball/SpaceCadetPinball.cpp index 8f7d047..c420c33 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.cpp +++ b/SpaceCadetPinball/SpaceCadetPinball.cpp @@ -21,8 +21,7 @@ int main() { // Testing with UI char cmdLine[1]{}; - pb::init(); - WinMain(winmain::hinst, 0, cmdLine, 10); + WinMain(GetModuleHandleA(nullptr), 0, cmdLine, 10); return 0; } diff --git a/SpaceCadetPinball/SpaceCadetPinball.rc b/SpaceCadetPinball/SpaceCadetPinball.rc index a2b5c32..50d6d33 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.rc +++ b/SpaceCadetPinball/SpaceCadetPinball.rc @@ -98,6 +98,24 @@ BEGIN END +///////////////////////////////////////////////////////////////////////////// +// +// RCDATA +// + +PBMSG_FT RCDATA "PB_MSGFT.bin" + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +ICON_1 ICON "icon_1.ico" + + ///////////////////////////////////////////////////////////////////////////// // // String Table diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj index b9c8cc9..2c1bede 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj @@ -30,14 +30,14 @@ Application true v141 - Unicode + NotSet Application false v141 true - Unicode + NotSet Application @@ -288,6 +288,12 @@ + + + + + + diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters index ab37c36..8ed2be1 100644 --- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters +++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters @@ -401,4 +401,14 @@ Resource Files + + + Resource Files + + + + + Resource Files + + \ No newline at end of file diff --git a/SpaceCadetPinball/TTextBox.cpp b/SpaceCadetPinball/TTextBox.cpp index 04cffb3..72e8aa5 100644 --- a/SpaceCadetPinball/TTextBox.cpp +++ b/SpaceCadetPinball/TTextBox.cpp @@ -196,6 +196,65 @@ void TTextBox::Draw() 255); return; } + auto text = this2->Message1->Text; + for (auto y = this2->OffsetY; ; y += font->Height) + { + auto curChar = *text; + if (!curChar || y + font->Height > this2->OffsetY + this2->Height) + break; + + auto totalWidth = 0; + char* textEndSpace = nullptr; + auto textEnd = text; + while (true) + { + auto maskedChar = curChar & 0x7F; + if (!maskedChar || maskedChar == '\n') + break; + auto charBmp = font->Chars[maskedChar]; + if (charBmp) + { + auto width = charBmp->Width + font->GapWidth + totalWidth; + if (width > this2->Width) + { + if (textEndSpace) + textEnd = textEndSpace; + break; + } + if (*textEnd == ' ') + textEndSpace = textEnd; + curChar = *(textEnd + 1); + totalWidth = width; + ++textEnd; + } + else + { + curChar = *textEnd; + } + } + + auto offX = this2->OffsetX; + while (text < textEnd) + { + auto charBmp = font->Chars[*text++ & 0x7F]; + if (charBmp) + { + auto height = charBmp->Height; + auto width = charBmp->Width; + if (render::background_bitmap) + gdrv::copy_bitmap_w_transparency(&render::vscreen, width, height, offX, y, charBmp, 0, 0); + else + gdrv::copy_bitmap(&render::vscreen, width, height, offX, y, charBmp, 0, 0); + font = this2->Font; + offX += charBmp->Width + font->GapWidth; + } + } + while ((*text & 0x7F) == ' ') + ++text; + if ((*text & 0x7F) == '\n') + ++text; + } + break; } } else diff --git a/SpaceCadetPinball/score.cpp b/SpaceCadetPinball/score.cpp index 177f210..dd037c8 100644 --- a/SpaceCadetPinball/score.cpp +++ b/SpaceCadetPinball/score.cpp @@ -3,6 +3,7 @@ #include "loader.h" #include "memory.h" #include "partman.h" +#include "winmain.h" score_msg_font_type* score::msg_fontp; @@ -44,17 +45,108 @@ scoreStruct* score::create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp) scoreStruct* score::dup(scoreStruct* score, int scoreIndex) { - scoreStruct* result = (scoreStruct*)memory::allocate(sizeof(scoreStruct)); + auto result = reinterpret_cast(memory::allocate(sizeof(scoreStruct))); if (result) memcpy(result, score, sizeof(scoreStruct)); return result; } -HRSRC score::load_msg_font(LPCSTR lpName) +void score::load_msg_font(LPCSTR lpName) { - return nullptr; + auto resHandle = FindResourceA(winmain::hinst, lpName, RT_RCDATA); + if (!resHandle) + return; + + auto resGlobal = LoadResource(winmain::hinst, resHandle); + if (!resGlobal) + return; + + auto rcData = static_cast<__int16*>(LockResource(resGlobal)); + + auto fontp = reinterpret_cast(memory::allocate(sizeof(score_msg_font_type))); + msg_fontp = fontp; + if (!fontp) + { + FreeResource(resGlobal); + return; + } + memset(fontp->Chars, 0, sizeof(fontp->Chars)); + + auto maxWidth = 0; + auto ptrToWidths = (char*)rcData + 6; + for (auto index = 128; index; index--) + { + if (*ptrToWidths > maxWidth) + maxWidth = *ptrToWidths; + ++ptrToWidths; + } + + auto height = rcData[2]; + auto tmpCharBur = memory::allocate(maxWidth * height + 4); + if (!tmpCharBur) + { + memory::free(msg_fontp); + msg_fontp = nullptr; + FreeResource(resGlobal); + return; + } + + msg_fontp->GapWidth = rcData[0]; + msg_fontp->Height = height; + + auto ptrToData = (char*)(rcData + 67); + int charInd; + for (charInd = 0; charInd < 128; charInd++) + { + auto width = *((char*)rcData + 6 + charInd); + if (!width) + continue; + + auto bmp = reinterpret_cast(memory::allocate(sizeof(gdrv_bitmap8))); + msg_fontp->Chars[charInd] = bmp; + if (!bmp) + { + break; + } + + if (gdrv::create_raw_bitmap(bmp, width, height, 0)) + { + memory::free(bmp); + msg_fontp->Chars[charInd] = nullptr; + break; + } + + auto sizeInBytes = height * width + 1; + memcpy(tmpCharBur + 3, ptrToData, sizeInBytes); + ptrToData += sizeInBytes; + + auto srcptr = tmpCharBur + 4; + auto dstPtr = &bmp->BmpBufPtr1[bmp->Stride * (bmp->Height - 1)]; + for (auto y = 0; y < height; ++y) + { + memcpy(dstPtr, srcptr, width); + srcptr += width; + dstPtr -= bmp->Stride; + } + } + + if (charInd != 128) + unload_msg_font(); + FreeResource(resGlobal); } void score::unload_msg_font() { + if (msg_fontp) + { + for (int i = 0; i < 128; i++) + { + if (msg_fontp->Chars[i]) + { + gdrv::destroy_bitmap(msg_fontp->Chars[i]); + memory::free(msg_fontp->Chars[i]); + } + } + msg_fontp = nullptr; + } } diff --git a/SpaceCadetPinball/score.h b/SpaceCadetPinball/score.h index a991324..7790e1f 100644 --- a/SpaceCadetPinball/score.h +++ b/SpaceCadetPinball/score.h @@ -24,8 +24,20 @@ struct scoreStruct struct score_msg_font_type { + int GapWidth; + int Height; + gdrv_bitmap8* Chars[128]; }; +struct score_font_rc +{ + short Header0; + short Header1; + short Height; + char SomeLen[128]; +}; + + class score { public: @@ -33,6 +45,6 @@ public: static int init(); static scoreStruct* create(LPCSTR fieldName, gdrv_bitmap8* renderBgBmp); static scoreStruct* dup(scoreStruct* score, int scoreIndex); - static HRSRC load_msg_font(LPCSTR lpName); + static void load_msg_font(LPCSTR lpName); static void unload_msg_font(); }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 16c7a5d..4355eda 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -139,7 +139,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIconA(hInstance, "ICON_1"); - WndClass.hCursor = LoadCursorA(nullptr, (LPCSTR)0x7F00); + WndClass.hCursor = LoadCursorA(nullptr, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)16; WndClass.lpszMenuName = "MENU_1"; WndClass.lpszClassName = windowClass; @@ -354,7 +354,7 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP int height = rect.bottom - rect.top; pb::window_size(&width, &height); - auto prevCursor = SetCursor(LoadCursorA(nullptr, (LPCSTR)IDC_WAIT)); + auto prevCursor = SetCursor(LoadCursorA(nullptr, IDC_WAIT)); gdrv::init(hinst, hWnd); auto voiceCount = options::get_int(nullptr, "Voices", 8); @@ -747,7 +747,7 @@ void winmain::end_pause() void winmain::new_game() { end_pause(); - HCURSOR prevCursor = SetCursor(LoadCursorA(nullptr, (LPCSTR)IDC_WAIT)); + HCURSOR prevCursor = SetCursor(LoadCursorA(nullptr, IDC_WAIT)); pb::replay_level(0); SetCursor(prevCursor); }