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