From c0c336500955a23e344651e5412c9d9d441ef4ee Mon Sep 17 00:00:00 2001 From: Ash Wolf Date: Wed, 28 Jun 2023 22:22:32 +0100 Subject: first pass of T2DLL --- src/T2DLL/GlobalFunc.cpp | 383 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 362 insertions(+), 21 deletions(-) (limited to 'src/T2DLL/GlobalFunc.cpp') diff --git a/src/T2DLL/GlobalFunc.cpp b/src/T2DLL/GlobalFunc.cpp index b210cc6..754f5cd 100644 --- a/src/T2DLL/GlobalFunc.cpp +++ b/src/T2DLL/GlobalFunc.cpp @@ -1,82 +1,423 @@ +#include "CResFile.h" #include "GlobalFunc.h" +#include "T2BitImage.h" +#include "T2OptionPluginList.h" +#include "T2TowerDoc.h" +#include "T2WorldDef.h" -char *strtokEx(char *, const char *, char **) { +T2SoundPlayer *Sounds; +CT2App *gT2App; +int gCommonColor[20]; +BOOL FFEnable; +DWORD FFBaseForce; +IDirectInput *FFgpdi; +IDirectInputDevice2W *FFJoystick; +IDirectInputEffect *FFBuild; +IDirectInputEffect *FFStatic; +T2TowerDoc *g_TowerDoc; + +char *strtokEx(char * inStr, const char * inSep, char ** ioLast) { +#line 11 + _ASSERT(!inStr || !*ioLast); + + if (inStr) { + *ioLast = NULL; + inStr += _mbsspn((const unsigned char *) inStr, (const unsigned char *) inSep); + } + + if (*ioLast) + inStr = *ioLast; + + char *work = inStr; + + if (inStr) { + work = inStr; + inStr = (char *) _mbspbrk((const unsigned char *) inStr, (const unsigned char *) inSep); + if (inStr) { + *inStr = 0; + inStr++; + inStr += _mbsspn((const unsigned char *) inStr, (const unsigned char *) inSep); + if (*inStr == 0) + inStr = NULL; + } + + *ioLast = inStr; + } + + return work; } -void InsetRect(RECT *, int, int) { +void InsetRect(RECT * ioRect, int inX, int inY) { + ioRect->top += inY; + ioRect->bottom -= inY; + ioRect->left += inX; + ioRect->right -= inX; } -void SetPt(POINT *, int, int) { +void SetPt(POINT * outPt, int inX, int inY) { + outPt->x = inX; + outPt->y = inY; } -HBITMAP Create256DIBitmap(HDC, int, int) { +HBITMAP Create256DIBitmap(HDC inDC, int inWidth, int inHeight) { + HBITMAP theBitmap = NULL; + + if (GetDeviceCaps(inDC, BITSPIXEL) == 8) { + theBitmap = CreateBitmap(inWidth, inHeight, 1, 8, NULL); + } else { + Bitmap *bitmap = (Bitmap *) malloc(sizeof(Bitmap)); + memset(&bitmap->header, 0, sizeof(BITMAPINFOHEADER)); + + bitmap->header.biSize = sizeof(BITMAPINFOHEADER); + bitmap->header.biWidth = inWidth; + bitmap->header.biHeight = inHeight; + bitmap->header.biBitCount = 8; + bitmap->header.biPlanes = 1; + bitmap->header.biClrUsed = 256; + bitmap->header.biClrImportant = 256; + + for (int i = 0; i < 256; i++) + bitmap->palette[i] = i; + + void *bits; + theBitmap = CreateDIBSection(inDC, (const BITMAPINFO *) bitmap, DIB_PAL_COLORS, &bits, NULL, 0); + + free(bitmap); + } + + return theBitmap; } -LOGPALETTE *ConvACTPalette(ACTPALETTEENTRY *) { +LOGPALETTE *ConvACTPalette(ACTPALETTEENTRY * inPalette) { + LOGPALETTE *pal = (LOGPALETTE *) malloc(sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)); + + for (int i = 0; i < 256; i++) { + pal->palPalEntry[i].peRed = inPalette[i].red; + pal->palPalEntry[i].peGreen = inPalette[i].green; + pal->palPalEntry[i].peBlue = inPalette[i].blue; + pal->palPalEntry[i].peFlags = 0; + } + + pal->palVersion = 0x300; + pal->palNumEntries = 256; + return pal; } -LOGPALETTE *LoadACTPaletteEntries(HINSTANCE, int) { +LOGPALETTE *LoadACTPaletteEntries(HINSTANCE inModule, int inResID) { + HRSRC theRes = FindResource(inModule, MAKEINTRESOURCE(inResID), "PALETTE"); + if (!theRes) + return NULL; + + HGLOBAL theResHandle = LoadResource(inModule, theRes); + if (SizeofResource(inModule, theRes) == 0x300) { + ACTPALETTEENTRY *act = (ACTPALETTEENTRY *) LockResource(theResHandle); + return ConvACTPalette(act); + } + + unsigned char *data = (unsigned char *) LockResource(theResHandle); + DWORD theResSize = sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY); + LOGPALETTE *theLogPalette = (LOGPALETTE *) malloc(theResSize); + memset(theLogPalette, 0, theResSize); + + theLogPalette->palVersion = 0x300; + theLogPalette->palNumEntries = 256; + + if (data[0] == 0 && data[1] == 0) { + data += 6; + + int entryCount = (data[0] << 8) + data[1]; + data += 2; + + for (int i = 0; i < entryCount; i++) { + theLogPalette->palPalEntry[data[1]].peRed = data[2]; + theLogPalette->palPalEntry[data[1]].peGreen = data[4]; + theLogPalette->palPalEntry[data[1]].peBlue = data[6]; + theLogPalette->palPalEntry[data[1]].peFlags = 0; + data += 8; + } + } else { + int entryCount = (data[0] << 8) + data[1]; + data += 16; + + for (int i = 0; i < entryCount; i++) { + theLogPalette->palPalEntry[i].peRed = data[0]; + theLogPalette->palPalEntry[i].peGreen = data[2]; + theLogPalette->palPalEntry[i].peBlue = data[4]; + theLogPalette->palPalEntry[i].peFlags = 0; + data += 16; + } + } + + return theLogPalette; } -void FFSetStaticForce(int, int) { +// 1001719C, not exported lmao +CPalette *LoadPaletteUnkName(HINSTANCE inModule, int inResID) { + LOGPALETTE *logPalette = LoadACTPaletteEntries(inModule, inResID); + if (!logPalette) + return NULL; + + logPalette->palPalEntry[253].peFlags = PC_RESERVED; + logPalette->palPalEntry[254].peFlags = PC_RESERVED; + + CPalette *thePalette = new CPalette; + thePalette->CreatePalette(logPalette); + free(logPalette); + + return thePalette; +} + +void FFSetStaticForce(int inX, int inY) { + if (!FFEnable) + return; + + LONG rglDirection[2] = { inX, inY }; + DICONSTANTFORCE cf; + cf.lMagnitude = (DWORD) sqrt((double)inX * (double)inX + (double)inY * (double)inY); + + DIEFFECT eff; + eff.dwSize = sizeof(DIEFFECT); + eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; + eff.cAxes = 2; + eff.rglDirection = rglDirection; + eff.lpEnvelope = NULL; + eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); + eff.lpvTypeSpecificParams = &cf; + + FFStatic->SetParameters(&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); } CString GetInstallSource() { + return GetMachineProfileString("Install", "Source", "Z:\\"); } CString GetInstallSourceDrive() { + CString path = GetMachineProfileString("Install", "Source", "Z:\\"); + return path.Left(1); } T2TowerDoc *GetCurrentT2TowerDoc() { + return g_TowerDoc; } HINSTANCE GetWorldModuleHandle() { + return GetCurrentT2TowerDoc()->towerDoc_vf170()->mModuleHandle; } -CString GetModuleName(HINSTANCE) { +CString GetModuleName(HINSTANCE inModule) { + char buf[512]; + GetModuleFileName(inModule, buf, 512); + + CString theName = _mbsrchr((const unsigned char *) buf, '\\') + 1; + return theName; } unsigned int TickCount() { + return (GetTickCount() * 60) / 1000; } -int DispatchOptionEvent(OPTIONEVENTTYPE, void *) { +BOOL DispatchOptionEvent(OPTIONEVENTTYPE inEventType, void * inData) { + return GetCurrentT2TowerDoc()->mOptionPluginList->DispatchEvent(inEventType, GetCurrentT2TowerDoc(), inData); } -CFile *OpenSubPluginFS(const char *, int, int, SUBPLUGINFSENTRY *) { +CFile *OpenSubPluginFS(const char * inPath, int inID1, int inID2, SUBPLUGINFSENTRY * outEntry) { + CFile *file = new CFile; + + if (!file->Open(inPath, CFile::modeRead)) { + delete file; + return NULL; + } + + char magic[2]; + file->Read(magic, 2); +#line 229 + _ASSERT(memcmp(magic, "SP", 2) == 0); + + unsigned int curEntry, count; + SUBPLUGINFSENTRY fsEntry; + file->Read(&count, sizeof(count)); + + for (curEntry = 0; curEntry < count; curEntry++) { + file->Read(&fsEntry, sizeof(fsEntry)); + if (fsEntry.spfse_m0 == inID2 && fsEntry.spfse_m4 == inID1) + break; + } + + if (curEntry == count) { + file->Close(); + delete file; + + CString err; + err.Format("CResFile::OpenResource(SubPlugin FS) ERROR : %s,%d,%d\n", inPath, inID2, inID1); + OutputDebugString(err); + return NULL; + } + + *outEntry = fsEntry; + file->Seek(fsEntry.spfse_m8, CFile::begin); + return file; } -void __Rep0(const char *, int, const char *) { +void __Rep0(const char * inFileName, int inLineNum, const char * inMessage) { + CString err; + err.Format("%s (%d)\n\n%s", inFileName, inLineNum, inMessage); + MessageBox(NULL, err, "ERROR", MB_ICONERROR); + _CrtDbgBreak(); } -void __Rep1(const char *, int, const char *, unsigned long) { +void __Rep1(const char * inFileName, int inLineNum, const char * inMessage, unsigned long inArg1) { + CString err; + err.Format(inMessage, inArg1); + __Rep0(inFileName, inLineNum, err); } -void __Rep2(const char *, int, const char *, unsigned long, unsigned long) { +void __Rep2(const char * inFileName, int inLineNum, const char * inMessage, unsigned long inArg1, unsigned long inArg2) { + CString err; + err.Format(inMessage, inArg1, inArg2); + __Rep0(inFileName, inLineNum, err); } -void GetTowerDirectory(char *) { +void GetTowerDirectory(char * outStr) { + GetModuleFileName(NULL, outStr, 1000); + *strrchr(outStr, '\\') = 0; + + char *p = strrchr(outStr, '\\'); + if (p && !_stricmp(p, "\\debug")) + *p = 0; + else if (p && !_stricmp(p, "\\release")) + *p = 0; + + strcat(outStr, "\\"); } CString GetTowerDirectory() { + char *buffer = (char *) malloc(1000); + GetTowerDirectory(buffer); + CString thePath = buffer; + free(buffer); + return thePath; } -CString LoadStringA(HINSTANCE, int, int) { +CString LoadString(HINSTANCE inModule, int inID, int inMaxSize) { + if (inModule == INSTANCE_EXE) + inModule = AfxGetInstanceHandle(); + else if (inModule == INSTANCE_WORLD) + inModule = GetWorldModuleHandle(); + + CString str; + char *buffer = (char *) malloc(inMaxSize + 1); + buffer[0] = 0; + + if (inModule != INSTANCE_ANY) { + str.Format("%d@%s", inID, GetModuleName(inModule)); + LoadString(inModule, inID, buffer, inMaxSize + 1); + } else { + str.Format("%d", inID); + if (!LoadString(GetWorldModuleHandle(), inID, buffer, inMaxSize + 1)) + LoadString(AfxGetInstanceHandle(), inID, buffer, inMaxSize + 1); + } + + if (buffer[0] != 0) + str = buffer; + + free(buffer); + return str; } -CString LoadStringTable(HINSTANCE, int, int) { +CString LoadStringTable(HINSTANCE inModule, int inID1, int inID2) { + if (inModule == INSTANCE_EXE) + inModule = AfxGetInstanceHandle(); + else if (inModule == INSTANCE_WORLD) + inModule = GetWorldModuleHandle(); + + CString str; + + if (inModule != INSTANCE_ANY) { + str.Format("%d-%d@%s", inID1, inID2, GetModuleName(inModule)); + CResFile theResFile; + if (theResFile.OpenResource(inModule, inID1, "STRTABLE")) { + int count; + theResFile >> count; + if (inID2 <= count) { + for (int i = 1; i <= inID2; i++) + theResFile >> str; + } + } + } else { + str.Format("%d-%d@%s", inID1, inID2); + + BOOL isOpen = false; + CResFile theResFile; + if (theResFile.OpenResource(GetWorldModuleHandle(), inID1, "STRTABLE")) + isOpen = true; + else if (theResFile.OpenResource(AfxGetInstanceHandle(), inID1, "STRTABLE")) + isOpen = true; + + if (isOpen) { + int count; + theResFile >> count; + if (inID2 <= count) { + for (int i = 1; i <= inID2; i++) + theResFile >> str; + } + } + } + + return str; } -void CopyPalette(LOGPALETTE *, LOGPALETTE *, int, int, int) { +void CopyPalette(LOGPALETTE *inSrc, LOGPALETTE *inDst, int inSrcIndex, int inDstIndex, int inCount) { + for (int i = 0; i < inCount; i++) { + inDst->palPalEntry[inDstIndex + i].peRed = inSrc->palPalEntry[inSrcIndex + i].peRed; + inDst->palPalEntry[inDstIndex + i].peGreen = inSrc->palPalEntry[inSrcIndex + i].peGreen; + inDst->palPalEntry[inDstIndex + i].peBlue = inSrc->palPalEntry[inSrcIndex + i].peBlue; + } } -void WriteMachineProfileString(const char *, const char *, const char *) { +void WriteMachineProfileString(const char * inKey, const char * inName, const char * inValue) { + CString subKey = "SOFTWARE\\OPeNBooK9003\\T2\\"; + subKey += inKey; + + HKEY key; + RegCreateKey(HKEY_LOCAL_MACHINE, subKey, &key); + RegSetValueEx(key, inName, 0, REG_SZ, (LPBYTE) inValue, strlen(inValue)); + RegCloseKey(key); } -void WriteMachineProfileInt(const char *, const char *, int) { +void WriteMachineProfileInt(const char * inKey, const char * inName, int inValue) { + CString value; + value.Format("%d", inValue); + WriteMachineProfileString(inKey, inName, value); } -CString GetMachineProfileString(const char *, const char *, const char *) { +CString GetMachineProfileString(const char * inKey, const char * inName, const char * inDefaultValue) { + CString subKey = "SOFTWARE\\OPeNBooK9003\\T2\\"; + subKey += inKey; + + CString result; + + HKEY key; + if (RegOpenKey(HKEY_LOCAL_MACHINE, subKey, &key) == ERROR_SUCCESS) { + DWORD type = REG_SZ; + DWORD bufferSize = 0x400; + char *buffer = (char *) malloc(bufferSize); + if (RegQueryValueEx(key, inName, NULL, &type, (LPBYTE) buffer, &bufferSize) == ERROR_SUCCESS) + result = buffer; + else + result = inDefaultValue; + + RegCloseKey(key); + free(buffer); + } else { + result = inDefaultValue; + } + + return result; } -int GetMachineProfileInt(const char *, const char *, int) { +int GetMachineProfileInt(const char * inKey, const char * inName, int inDefaultValue) { + CString value; + value.Format("%d", inDefaultValue); + value = GetMachineProfileString(inKey, inName, value); + return atoi(value); } -- cgit v1.2.3