diff --git a/SpaceCadetPinball/SpaceCadetPinball.cpp b/SpaceCadetPinball/SpaceCadetPinball.cpp
index 61ca286..dd7bdf6 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.cpp
+++ b/SpaceCadetPinball/SpaceCadetPinball.cpp
@@ -17,7 +17,9 @@ int main()
{
std::cout << "Hello World!\n";
- pinball::hinst = GetModuleHandle(nullptr);
+ pinball::hinst = GetModuleHandleA(nullptr);
+ char cmdLine[1];
+ WinMain(pinball::hinst, 0, cmdLine, 0);
objlist_class d = objlist_class(2, 4);
for (int i = 0; i < 100; i++)
@@ -65,6 +67,7 @@ int main()
if (rsc)
printf_s("%d:\t%s\n", i, rsc);
}
+
//DatParser::Parse(dataFileName);
std::cout << "Goodby World!\n";
}
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
index e07fc42..6656756 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj
@@ -96,6 +96,7 @@
Console
true
+ Comctl32.lib;%(AdditionalDependencies)
@@ -154,7 +155,9 @@
+
+
@@ -191,11 +194,14 @@
+
+
+
Create
@@ -236,6 +242,7 @@
+
diff --git a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
index 515e5d8..bee9900 100644
--- a/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
+++ b/SpaceCadetPinball/SpaceCadetPinball.vcxproj.filters
@@ -138,6 +138,15 @@
Header Files\PinballComponents
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
@@ -254,6 +263,15 @@
Source Files\PinballComponents
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
diff --git a/SpaceCadetPinball/TPinballTable.cpp b/SpaceCadetPinball/TPinballTable.cpp
index 4e64404..733844b 100644
--- a/SpaceCadetPinball/TPinballTable.cpp
+++ b/SpaceCadetPinball/TPinballTable.cpp
@@ -3,6 +3,7 @@
#include "loader.h"
+#include "memory.h"
#include "pinball.h"
#include "TBall.h"
#include "TBlocker.h"
@@ -196,7 +197,7 @@ TPinballTable::~TPinballTable()
{
if (*scorePtr)
{
- free(*scorePtr);
+ memory::free(*scorePtr);
*scorePtr = nullptr;
}
scorePtr += 7;
@@ -205,12 +206,12 @@ TPinballTable::~TPinballTable()
while (index);
if (ScorePlayerNumber1)
{
- free(ScorePlayerNumber1);
+ memory::free(ScorePlayerNumber1);
ScorePlayerNumber1 = nullptr;
}
if (ScoreBallcount)
{
- free(ScoreBallcount);
+ memory::free(ScoreBallcount);
ScoreBallcount = nullptr;
}
for (auto i = LightGroup; ; i = static_cast(ListP1->Get(0)))
diff --git a/SpaceCadetPinball/loader.cpp b/SpaceCadetPinball/loader.cpp
index d25e4f4..3ffb67e 100644
--- a/SpaceCadetPinball/loader.cpp
+++ b/SpaceCadetPinball/loader.cpp
@@ -1,6 +1,8 @@
#include "pch.h"
#include "loader.h"
+
+#include "memory.h"
#include "partman.h"
#include "pinball.h"
@@ -138,7 +140,7 @@ void loader::unload()
while (index < sound_count);
}
if (sound_list[index].PtrToSmth)
- memoryfree(sound_list[index].PtrToSmth);
+ memory::free(sound_list[index].PtrToSmth);
sound_count = 1;
}
diff --git a/SpaceCadetPinball/memory.cpp b/SpaceCadetPinball/memory.cpp
new file mode 100644
index 0000000..3d7838a
--- /dev/null
+++ b/SpaceCadetPinball/memory.cpp
@@ -0,0 +1,58 @@
+#include "pch.h"
+#include "memory.h"
+
+unsigned int memory::use_total;
+int memory::critical_allocation;
+void (*memory::critical_callback)();
+
+void memory::init(void (*callback)())
+{
+ critical_callback = callback;
+}
+
+char* memory::allocate(unsigned int size)
+{
+ char* buf = static_cast(malloc(size + 4));
+ if (buf)
+ {
+ *(unsigned int*)buf = size << 8;
+ use_total += size + 4;
+ *buf = size >= 0xFFDC ? -91 : 90;
+ return buf + 4;
+ }
+ if (critical_allocation && critical_callback)
+ critical_callback();
+ return nullptr;
+}
+
+void memory::free(void* buf)
+{
+ unsigned int* bufStart = static_cast(buf) - 1;
+ use_total -= (*bufStart >> 8) + 4;
+ char firstChar = *(char*)bufStart;
+ if (firstChar == 90 || firstChar == -91)
+ std::free(bufStart);
+ else
+ assertm(false, "Unknown memory type");
+}
+
+char* memory::realloc(void* buf, unsigned int size)
+{
+ if (!buf)
+ return allocate(size);
+
+ char* bufStart = static_cast(buf) - 4;
+ use_total -= *(unsigned int*)bufStart >> 8;
+ if (*bufStart != 90 && *bufStart != -91 ||
+ (bufStart = static_cast(std::realloc(bufStart, size + 4))) != nullptr)
+ {
+ char bufType = *bufStart;
+ *(unsigned int*)bufStart = size << 8;
+ use_total += size;
+ *bufStart = bufType;
+ return bufStart + 4;
+ }
+ if (critical_allocation && critical_callback)
+ critical_callback();
+ return nullptr;
+}
diff --git a/SpaceCadetPinball/memory.h b/SpaceCadetPinball/memory.h
new file mode 100644
index 0000000..d7e4a50
--- /dev/null
+++ b/SpaceCadetPinball/memory.h
@@ -0,0 +1,13 @@
+#pragma once
+class memory
+{
+public:
+ static void init(void (*callback)(void));
+ static char* allocate(unsigned int size);
+ static void free(void* buf);
+ static char* realloc(void* buf, unsigned int size);
+
+ static unsigned int use_total;
+ static int critical_allocation;
+ static void (*critical_callback)();
+};
diff --git a/SpaceCadetPinball/objlist_class.cpp b/SpaceCadetPinball/objlist_class.cpp
index 7a3d0f1..8a4a2b4 100644
--- a/SpaceCadetPinball/objlist_class.cpp
+++ b/SpaceCadetPinball/objlist_class.cpp
@@ -1,6 +1,8 @@
#include "pch.h"
#include "objlist_class.h"
#include
+
+#include "memory.h"
// v1 from Ida
objlist_class::objlist_class(int SizeInt, int growSize)
@@ -12,7 +14,7 @@ objlist_class::objlist_class(int SizeInt, int growSize)
objlist_class::~objlist_class()
{
if (ListPtr)
- free(ListPtr);
+ memory::free(ListPtr);
}
void objlist_class::Add(void* value)
@@ -42,7 +44,7 @@ void* objlist_class::Get(int index)
objlist_struct1* objlist_class::objlist_new(int sizeInt)
{
- objlist_struct1* result = (objlist_struct1 *)malloc(sizeof(void*) * sizeInt + sizeof(objlist_struct1));
+ objlist_struct1* result = (objlist_struct1 *)memory::allocate(sizeof(void*) * sizeInt + sizeof(objlist_struct1));
if (!result)
return result;
result->Count = 0;
@@ -67,7 +69,7 @@ objlist_struct1* objlist_class::objlist_grow(objlist_struct1* ptrToStruct, int g
int newSizeInt = growSize + ptrToStruct->Count;
if (newSizeInt <= ptrToStruct->Size)
return resultPtr;
- objlist_struct1* resultPtr2 = (objlist_struct1*)realloc(ptrToStruct, sizeof(void*) * newSizeInt + sizeof(objlist_struct1));
+ objlist_struct1* resultPtr2 = (objlist_struct1*)memory::realloc(ptrToStruct, sizeof(void*) * newSizeInt + sizeof(objlist_struct1));
if (!resultPtr2)
return resultPtr;
resultPtr = resultPtr2;
diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp
new file mode 100644
index 0000000..e39ef0a
--- /dev/null
+++ b/SpaceCadetPinball/options.cpp
@@ -0,0 +1,118 @@
+#include "pch.h"
+#include "options.h"
+#include "memory.h"
+
+LPCSTR options::OptionsRegPath;
+LPSTR options::OptionsRegPathCur;
+
+void options::path_init(LPCSTR regPath)
+{
+ char* buf = memory::allocate(lstrlenA(regPath) + 1);
+ OptionsRegPath = buf;
+ if (buf)
+ lstrcpyA(buf, regPath);
+}
+
+void options::path_uninit()
+{
+ if (OptionsRegPath)
+ memory::free((void*)OptionsRegPath);
+ OptionsRegPath = nullptr;
+}
+
+LPCSTR options::path(LPCSTR regPath)
+{
+ char* buf = OptionsRegPathCur;
+ if (!OptionsRegPathCur)
+ {
+ buf = memory::allocate(0x7D0u);
+ OptionsRegPathCur = buf;
+ if (!buf)
+ return OptionsRegPath;
+ }
+ lstrcpyA(buf, OptionsRegPath);
+ if (!regPath)
+ return OptionsRegPathCur;
+ lstrcatA(OptionsRegPathCur, "\\");
+ lstrcatA(OptionsRegPathCur, regPath);
+ return OptionsRegPathCur;
+}
+
+void options::path_free()
+{
+ if (OptionsRegPathCur)
+ memory::free(OptionsRegPathCur);
+ OptionsRegPathCur = nullptr;
+}
+
+
+int options::get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue)
+{
+ DWORD dwDisposition; // [esp+4h] [ebp-8h]
+
+ HKEY result = (HKEY)defaultValue, Data = (HKEY)defaultValue;
+ if (!OptionsRegPath)
+ return defaultValue;
+ LPCSTR regPath = path(optPath);
+ if (!RegCreateKeyExA(HKEY_CURRENT_USER, regPath, 0, nullptr, 0, 0xF003Fu, nullptr, &result, &dwDisposition))
+ {
+ optPath = (LPCSTR)4;
+ RegQueryValueExA(result, lpValueName, nullptr, nullptr, (LPBYTE)&Data, (LPDWORD)&optPath);
+ RegCloseKey(result);
+ }
+ path_free();
+ return (int)Data;
+}
+
+void options::set_int(LPCSTR optPath, LPCSTR lpValueName, int data)
+{
+ DWORD dwDisposition; // [esp+4h] [ebp-4h]
+
+ if (OptionsRegPath)
+ {
+ const CHAR* regPath = path(optPath);
+ if (!RegCreateKeyExA(HKEY_CURRENT_USER, regPath, 0, nullptr, 0, 0xF003Fu, nullptr, (PHKEY)&optPath,
+ &dwDisposition))
+ {
+ RegSetValueExA((HKEY)optPath, lpValueName, 0, 4u, (const BYTE*)&data, 4u);
+ RegCloseKey((HKEY)optPath);
+ }
+ path_free();
+ }
+}
+
+void options::get_string(LPCSTR optPath, LPCSTR lpValueName, LPSTR lpString1, LPCSTR lpString2, int iMaxLength)
+{
+ const CHAR* v5 = (const CHAR*)iMaxLength;
+ lstrcpynA(lpString1, lpString2, iMaxLength);
+ if (OptionsRegPath)
+ {
+ const CHAR* regPath = path(optPath);
+ if (!RegCreateKeyExA(HKEY_CURRENT_USER, regPath, 0, nullptr, 0, 0xF003Fu, nullptr, (PHKEY)&iMaxLength,
+ (LPDWORD)&optPath))
+ {
+ lpString2 = v5;
+ RegQueryValueExA((HKEY)iMaxLength, lpValueName, nullptr, nullptr, (LPBYTE)lpString1, (LPDWORD)&lpString2);
+ RegCloseKey((HKEY)iMaxLength);
+ }
+ path_free();
+ }
+}
+
+void options::set_string(LPCSTR optPath, LPCSTR lpValueName, LPCSTR value)
+{
+ DWORD dwDisposition; // [esp+4h] [ebp-4h]
+
+ if (OptionsRegPath)
+ {
+ const CHAR* regPath = path(optPath);
+ if (!RegCreateKeyExA(HKEY_CURRENT_USER, regPath, 0, nullptr, 0, 0xF003Fu, nullptr, (PHKEY)&optPath,
+ &dwDisposition))
+ {
+ int v4 = lstrlenA(value);
+ RegSetValueExA((HKEY)optPath, lpValueName, 0, 1u, (const BYTE*)value, v4 + 1);
+ RegCloseKey((HKEY)optPath);
+ }
+ path_free();
+ }
+}
diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h
new file mode 100644
index 0000000..f4b3375
--- /dev/null
+++ b/SpaceCadetPinball/options.h
@@ -0,0 +1,16 @@
+#pragma once
+class options
+{
+public:
+ static void path_init(LPCSTR regPath);
+ static void path_uninit();
+ static int get_int(LPCSTR optPath, LPCSTR lpValueName, int defaultValue);
+ static void set_int(LPCSTR optPath, LPCSTR lpValueName, int data);
+ static void get_string(LPCSTR optPath, LPCSTR lpValueName, LPSTR lpString1, LPCSTR lpString2, int iMaxLength);
+ static void set_string(LPCSTR optPath, LPCSTR lpValueName, LPCSTR value);
+private:
+ static LPCSTR OptionsRegPath;
+ static LPSTR OptionsRegPathCur;
+ static LPCSTR path(LPCSTR regPath);
+ static void path_free();
+};
diff --git a/SpaceCadetPinball/partman.cpp b/SpaceCadetPinball/partman.cpp
index 43e6a96..409852f 100644
--- a/SpaceCadetPinball/partman.cpp
+++ b/SpaceCadetPinball/partman.cpp
@@ -1,6 +1,8 @@
#include "pch.h"
#include "partman.h"
+#include "memory.h"
+
short partman::_field_size[] = {
2, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
};
@@ -24,7 +26,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
_lclose(fileHandle);
return nullptr;
}
- datFile = (datFileStruct*)memoryallocate(sizeof(datFileStruct));
+ datFile = (datFileStruct*)memory::allocate(sizeof(datFileStruct));
if (!datFile)
{
_lclose(fileHandle);
@@ -37,12 +39,12 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
else
{
int lenOfStr = lstrlenA(Buffer.Description);
- auto descriptionBuf = (char*)memoryallocate(lenOfStr + 1);
+ auto descriptionBuf = (char*)memory::allocate(lenOfStr + 1);
datFile->Description = descriptionBuf;
if (!descriptionBuf)
{
_lclose(fileHandle);
- memoryfree(datFile);
+ memory::free(datFile);
return nullptr;
}
lstrcpyA(descriptionBuf, Buffer.Description);
@@ -50,26 +52,26 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
if (Buffer.Unknown)
{
- auto unknownBuf = (char*)memoryallocate(Buffer.Unknown);
+ auto unknownBuf = (char*)memory::allocate(Buffer.Unknown);
if (!unknownBuf)
{
_lclose(fileHandle);
if (datFile->Description)
- memoryfree(datFile->Description);
- memoryfree(datFile);
+ memory::free(datFile->Description);
+ memory::free(datFile);
return nullptr;
}
_lread(fileHandle, static_cast(unknownBuf), Buffer.Unknown);
- memoryfree(unknownBuf);
+ memory::free(unknownBuf);
}
- groupDataBuf = (datGroupData**)memoryallocate(sizeof(void*) * Buffer.NumberOfGroups);
+ groupDataBuf = (datGroupData**)memory::allocate(sizeof(void*) * Buffer.NumberOfGroups);
datFile->GroupData = groupDataBuf;
if (!groupDataBuf)
{
if (datFile->Description)
- memoryfree(datFile->Description);
- memoryfree(datFile);
+ memory::free(datFile->Description);
+ memory::free(datFile);
return nullptr;
}
@@ -83,7 +85,7 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
groupDataSize = 0;
else
groupDataSize = entryCount - 1;
- datFile->GroupData[groupIndex] = (datGroupData*)memoryallocate(
+ datFile->GroupData[groupIndex] = (datGroupData*)memory::allocate(
sizeof(datEntryData) * groupDataSize + sizeof(datGroupData));
datGroupData* groupData = datFile->GroupData[groupIndex];
if (!groupData)
@@ -105,22 +107,22 @@ datFileStruct* partman::load_records(LPCSTR lpFileName)
if (entryType == Bitmap8bit)
{
_hread(fileHandle, &bmpHeader, 14);
- char* bmpBuffer = (char*)memoryallocate(0x25u);
+ char* bmpBuffer = (char*)memory::allocate(0x25u);
entryData->Buffer = bmpBuffer;
if (!bmpBuffer)
goto LABEL_41;
/*if (bmpHeader.Unknown2 & 2 ? gdrv_create_bitmap((int)bmpBuffer, bmpHeader.Width, bmpHeader.Height) : gdrv_create_raw_bitmap((int)bmpBuffer, bmpHeader.Width, bmpHeader.Height, bmpHeader.Unknown2 & 1))
goto LABEL_41;*/
//_hread(fileHandle, *(LPVOID*)(entryData->Buffer + 8), bmpHeader.Size);
- char* tempBuff = (char*)memoryallocate(bmpHeader.Size);
+ char* tempBuff = (char*)memory::allocate(bmpHeader.Size);
_hread(fileHandle, tempBuff, bmpHeader.Size);
- memoryfree(tempBuff);
+ memory::free(tempBuff);
//*((int*)entryData->Buffer + 29) = bmpHeader.XPosition;
//*((int*)entryData->Buffer + 33) = bmpHeader.YPosition;
}
else
{
- char* entryBuffer = (char*)memoryallocate(fieldSize);
+ char* entryBuffer = (char*)memory::allocate(fieldSize);
entryData->Buffer = entryBuffer;
if (!entryBuffer)
goto LABEL_41;
@@ -165,20 +167,20 @@ void partman::unload_records(datFileStruct* datFile)
{
//if (HIWORD(entry->EntryType) == 1)
//gdrv_destroy_bitmap(entry->Buffer);
- memoryfree(entry->Buffer);
+ memory::free(entry->Buffer);
}
++entryIndex;
++entry;
}
while (entryIndex < group->EntryCount);
}
- memoryfree(group);
+ memory::free(group);
}
}
if (datFile->Description)
- memoryfree(datFile->Description);
- memoryfree(datFile->GroupData);
- memoryfree(datFile);
+ memory::free(datFile->Description);
+ memory::free(datFile->GroupData);
+ memory::free(datFile);
}
char* partman::field(datFileStruct* datFile, int groupIndex, datFieldTypes targetEntryType)
diff --git a/SpaceCadetPinball/pch.h b/SpaceCadetPinball/pch.h
index 7388b49..abc1f98 100644
--- a/SpaceCadetPinball/pch.h
+++ b/SpaceCadetPinball/pch.h
@@ -14,9 +14,10 @@
#include
#include
#include
+#include
//#include
-#define memoryallocate(x) malloc(x);
-#define memoryfree(x) free(x);
+// Use (void) to silent unused warnings.
+#define assertm(exp, msg) assert(((void)msg, exp))
#endif //PCH_H
diff --git a/SpaceCadetPinball/pinball.cpp b/SpaceCadetPinball/pinball.cpp
index 38d4c23..a0ca96a 100644
--- a/SpaceCadetPinball/pinball.cpp
+++ b/SpaceCadetPinball/pinball.cpp
@@ -1,5 +1,6 @@
#include "pch.h"
#include "pinball.h"
+#include "memory.h"
int pinball::quickFlag = 0;
@@ -9,6 +10,8 @@ TTextBox* pinball::MissTextBox;
char pinball::getRcBuffer[6 * 256];
int pinball::rc_string_slot = 0;
HINSTANCE pinball::hinst;
+char pinball::WindowName[2]{};
+char pinball::DatFileName[300]{};
char* pinball::get_rc_string(int uID, int a2)
diff --git a/SpaceCadetPinball/pinball.h b/SpaceCadetPinball/pinball.h
index 77e997d..cc90660 100644
--- a/SpaceCadetPinball/pinball.h
+++ b/SpaceCadetPinball/pinball.h
@@ -9,9 +9,10 @@ public:
static TTextBox* InfoTextBox;
static TTextBox* MissTextBox;
static HINSTANCE hinst;
+ static char WindowName[2];
+ static char DatFileName[300];
static char* get_rc_string(int uID, int a2);
private:
- static char getRcBuffer[256*6];
+ static char getRcBuffer[256 * 6];
static int rc_string_slot;
};
-
diff --git a/SpaceCadetPinball/score.cpp b/SpaceCadetPinball/score.cpp
index 539ac42..25ec533 100644
--- a/SpaceCadetPinball/score.cpp
+++ b/SpaceCadetPinball/score.cpp
@@ -1,12 +1,13 @@
#include "pch.h"
#include "score.h"
#include "loader.h"
+#include "memory.h"
#include "partman.h"
scoreStruct* score::create(LPCSTR fieldName, int renderBgBmp)
{
- scoreStruct* score = (scoreStruct*)memoryallocate(sizeof(scoreStruct));
+ scoreStruct* score = (scoreStruct*)memory::allocate(sizeof(scoreStruct));
if (!score)
return nullptr;
score->Unknown1 = -9999;
@@ -14,7 +15,7 @@ scoreStruct* score::create(LPCSTR fieldName, int renderBgBmp)
__int16* shortArr = (__int16*)partman::field_labeled(loader::loader_table, fieldName, ShortArray);
if (!shortArr)
{
- memoryfree(score);
+ memory::free(score);
return nullptr;
}
int groupIndex = *shortArr++;
@@ -37,7 +38,7 @@ scoreStruct* score::create(LPCSTR fieldName, int renderBgBmp)
scoreStruct* score::dup(scoreStruct* score, int scoreIndex)
{
- scoreStruct* result = (scoreStruct*)memoryallocate(0x44u);
+ scoreStruct* result = (scoreStruct*)memory::allocate(sizeof(scoreStruct));
if (result)
memcpy(result, score, sizeof(scoreStruct));
return result;
diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp
new file mode 100644
index 0000000..1ddd108
--- /dev/null
+++ b/SpaceCadetPinball/winmain.cpp
@@ -0,0 +1,133 @@
+#include "pch.h"
+#include "winmain.h"
+#include "memory.h"
+#include "pinball.h"
+#include "options.h"
+
+int iFrostUniqueMsg;
+
+//HWND, UINT, WPARAM, LPARAM
+//typedef LRESULT (CALLBACK* WNDPROC)(HWND, UINT, WPARAM, LPARAM);
+LRESULT CALLBACK message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM LPARAM)
+{
+ return 0;
+}
+
+int check_expiration_date()
+{
+ return 0;
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
+{
+ memory::init(winmain_memalloc_failure);
+ ++memory::critical_allocation;
+ auto optionsRegPath = pinball::get_rc_string(165, 0);
+ options::path_init(optionsRegPath);
+ auto regSpaceCadet = pinball::get_rc_string(166, 0);
+
+ if (options::get_int(regSpaceCadet, "Table Version", 1) <= 1)
+ {
+ auto tmpBuf = memory::allocate(0x1F4u);
+ if (!tmpBuf)
+ {
+ options::path_uninit();
+ return 0;
+ }
+
+ options::set_int(regSpaceCadet, "Table Version", 1u);
+ GetModuleFileNameA(pinball::hinst, tmpBuf, 0x1F4u);
+ options::set_string(regSpaceCadet, "Table Exe", tmpBuf);
+ options::set_string(regSpaceCadet, "Table Name", pinball::get_rc_string(169, 0));
+ options::set_string(nullptr, "Last Table Played", regSpaceCadet);
+ memory::free(static_cast(tmpBuf));
+ tmpBuf = memory::allocate(0x1F4u);
+ if (tmpBuf)
+ {
+ auto tmpBuf2 = memory::allocate(0x1F4u);
+ if (tmpBuf2)
+ {
+ char Buffer[40];
+ for (int i = 0; i < 32700; ++i)
+ {
+ sprintf_s(Buffer, "Table%d", i);
+ options::get_string(nullptr, Buffer, tmpBuf, pinball::WindowName, 500);
+ if (!*tmpBuf)
+ break;
+ options::get_string(tmpBuf, "Table Name", tmpBuf2, pinball::WindowName, 500);
+ if (!lstrcmpA(tmpBuf2, pinball::get_rc_string(169, 0)))
+ goto LABEL_15;
+ if (!*tmpBuf2)
+ break;
+ }
+ options::set_string(nullptr, Buffer, regSpaceCadet);
+ LABEL_15:
+ memory::free(tmpBuf2);
+ }
+ memory::free(tmpBuf);
+ }
+ }
+ else
+ {
+ auto tmpBuf = memory::allocate(0x1F4u);
+ if (!tmpBuf)
+ {
+ options::path_uninit();
+ return 0;
+ }
+ options::get_string(regSpaceCadet, "Shell Exe", tmpBuf, pinball::WindowName, 500);
+ auto execRes = WinExec(tmpBuf, 5u);
+ memory::free(tmpBuf);
+ if (execRes >= 32)
+ {
+ options::path_uninit();
+ return 0;
+ }
+ }
+ --memory::critical_allocation;
+
+ pinball::quickFlag = strstr(lpCmdLine, "-quick") != 0;
+ pinball::hinst = hInstance;
+ options::get_string(regSpaceCadet, "Pinball Data", pinball::DatFileName, pinball::get_rc_string(168, 0), 300);
+
+ iFrostUniqueMsg = RegisterWindowMessageA("PinballThemeSwitcherUniqueMsgString");
+ auto windowHandle= FindWindowA(pinball::get_rc_string(167, 0), nullptr);
+ if (windowHandle)
+ {
+ SendMessageA(windowHandle, iFrostUniqueMsg, 0, 0);
+ return 0;
+ }
+
+ if (check_expiration_date())
+ return 0;
+
+ INITCOMMONCONTROLSEX picce{};
+ picce.dwSize = 8;
+ picce.dwICC = 5885;
+ InitCommonControlsEx(&picce);
+
+ WNDCLASSA WndClass;
+ WndClass.style = 4104;
+ WndClass.lpfnWndProc = message_handler;
+ WndClass.cbClsExtra = 0;
+ WndClass.cbWndExtra = 0;
+ WndClass.hInstance = hInstance;
+ WndClass.hIcon = LoadIconA(hInstance, "ICON_1");
+ WndClass.hCursor = LoadCursorA(0, (LPCSTR)0x7F00);
+ WndClass.hbrBackground = (HBRUSH)16;
+ WndClass.lpszMenuName = "MENU_1";
+ WndClass.lpszClassName = pinball::get_rc_string(167, 0);
+ //auto tmpBuf = splash_screen((int)hInstance, "splash_bitmap", "splash_bitmap");
+ RegisterClassA(&WndClass);
+}
+
+void winmain_memalloc_failure()
+{
+ /*midi_music_stop();
+ Sound_Close();
+ gdrv_uninit();*/
+ char* caption = pinball::get_rc_string(170, 0);
+ char* text = pinball::get_rc_string(179, 0);
+ MessageBoxA(nullptr, text, caption, 0x2030u);
+ _exit(1);
+}
diff --git a/SpaceCadetPinball/winmain.h b/SpaceCadetPinball/winmain.h
new file mode 100644
index 0000000..c3b7628
--- /dev/null
+++ b/SpaceCadetPinball/winmain.h
@@ -0,0 +1,4 @@
+#pragma once
+
+static int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
+static void winmain_memalloc_failure();