commit b73851c4713dde0c4e876a9b5b7df4bff3e8f31d Author: snow flurry Date: Wed Mar 20 23:09:10 2024 -0700 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..432ed46 --- /dev/null +++ b/.gitignore @@ -0,0 +1,399 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml + diff --git a/BUILDING.TXT b/BUILDING.TXT new file mode 100644 index 0000000..87dface --- /dev/null +++ b/BUILDING.TXT @@ -0,0 +1,11 @@ +Still gotta work on this, sorry! + +For the impatient/desperate: This was built with Visual Studio 2005 on +Windows XP. For the libXMP parts, I used an old version of CMake (3.12?) +with a command line like the following: + + cmake -DCMAKE_BUILD_TYPE= -DBUILD_SHARED=OFF + -DLIBXMP_CFLAGS= -G "NMake Makefiles" <...> + +The official release is built with Release_ANSI for maximum +compatibility. diff --git a/Keygender32.sln b/Keygender32.sln new file mode 100644 index 0000000..787b3b9 --- /dev/null +++ b/Keygender32.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Keygender32", "Keygender32\Keygender32.vcproj", "{8E21754C-D79C-4B94-B139-BB91D252FF3F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug_ANSI|Win32 = Debug_ANSI|Win32 + Debug|Win32 = Debug|Win32 + Release_ANSI|Win32 = Release_ANSI|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Debug_ANSI|Win32.ActiveCfg = Debug_ANSI|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Debug_ANSI|Win32.Build.0 = Debug_ANSI|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Debug|Win32.ActiveCfg = Debug|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Debug|Win32.Build.0 = Debug|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Release_ANSI|Win32.ActiveCfg = Release_ANSI|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Release_ANSI|Win32.Build.0 = Release_ANSI|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Release|Win32.ActiveCfg = Release|Win32 + {8E21754C-D79C-4B94-B139-BB91D252FF3F}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Keygender32/BGM.c b/Keygender32/BGM.c new file mode 100644 index 0000000..72b4b51 --- /dev/null +++ b/Keygender32/BGM.c @@ -0,0 +1,385 @@ +#include "stdafx.h" +#define _BGM_DEFINE_ +#include "BGM.h" +#include "resource.h" +#include +#include "Debug.h" + +static DWORD WINAPI MusicThreadProc(LPVOID); + +struct _BgmState { + CRITICAL_SECTION cs; // to sync shutdown + LPWAVEFORMATEX pwfx; // wave-out data + HANDLE hThread; // audio thread + HANDLE hDone; // Are we done? + HANDLE hPause; // Play/Pause + BOOL bPaused; // Are we paused? +}; + +int +TogglePlayPause(BgmState state) +{ + BOOL bRet; + + if (!state) { + SetLastError(ERROR_INVALID_PARAMETER); + return -1; + } + + bRet = state->bPaused; + state->bPaused = !state->bPaused; + + if (!SetEvent(state->hPause)) { + state->bPaused = bRet; + return -1; + } + + return state->bPaused; +} + +BOOL +PrepareMusic(HINSTANCE hInstance, + BgmState *state) +{ + HANDLE hHeap = GetProcessHeap(); + LPWAVEFORMATEX pwfx = NULL; + int bIdx; + DWORD dwIgnore; + BOOL bFound = FALSE; + struct _BgmState *sTmp = NULL; + const DWORD dwTestFormats[] = { + 44100, + 22050, + 11025, + 8000, + }; + + MusicStartFailReason = "Couldn't verify parameters"; + + if (!hInstance || !state) return FALSE; + // TODO: do we even bother? we'll error out later + MusicStartFailReason = "Couldn't get number of waveOut devices"; + if (!waveOutGetNumDevs()) return FALSE; + + MusicStartFailReason = "Couldn't allocate memory"; + sTmp = HeapAlloc(hHeap, + HEAP_ZERO_MEMORY, + sizeof(struct _BgmState)); + if (!state) return FALSE; + + pwfx = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(WAVEFORMATEX)); + if (!pwfx) return FALSE; + + pwfx->wFormatTag = WAVE_FORMAT_PCM; + pwfx->nChannels = 2; + pwfx->wBitsPerSample = 16; + for (bIdx = 0; bIdx < (sizeof(dwTestFormats) / sizeof(DWORD)); bIdx++) { + MMRESULT mRes; + + pwfx->nSamplesPerSec = dwTestFormats[bIdx]; + pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nChannels; + pwfx->nBlockAlign = 2; // (1 channel * 16 bits) / (1 byte / 8 bits) + pwfx->cbSize = 0; + + mRes = waveOutOpen(NULL, + WAVE_MAPPER, + pwfx, + 0, 0, + WAVE_FORMAT_QUERY); + if (mRes == MMSYSERR_NOERROR) { + bFound = TRUE; + break; + } + } + + MusicStartFailReason = "Couldn't find a working sound device"; + // did we find a working sound device? + if (!bFound) { + HeapFree(hHeap, 0, pwfx); + HeapFree(hHeap, 0, sTmp); + return FALSE; + } + + sTmp->pwfx = pwfx; + MusicStartFailReason = "Couldn't create an event?"; + // build the sync event used for ending the thread + sTmp->hDone = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!sTmp->hDone) { + HeapFree(hHeap, 0, pwfx); + HeapFree(hHeap, 0, sTmp); + return FALSE; + } + + MusicStartFailReason = "Couldn't create another event???"; + sTmp->hPause = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!sTmp->hDone) { + HeapFree(hHeap, 0, pwfx); + HeapFree(hHeap, 0, sTmp); + return FALSE; + } + + MusicStartFailReason = "Couldn't create the music thread????????"; + sTmp->hThread = CreateThread(NULL, + 0, + MusicThreadProc, + sTmp, + 0, + &dwIgnore); + + if (!sTmp->hThread) { + HeapFree(hHeap, 0, pwfx); + HeapFree(hHeap, 0, sTmp); + return FALSE; + } + + *state = sTmp; + + MusicStartFailReason = "Everything's fine actually ??????????????"; + return TRUE; +} + +struct WaveBuf { + WAVEHDR *hdr; + struct WaveBuf *prev; + struct WaveBuf *next; +}; + +static DWORD WINAPI +MusicThreadProc(LPVOID lpParam) +{ + BgmState state = (BgmState)lpParam; + xmp_context xCtx = NULL; + HWAVEOUT hwOut = NULL; // audio out dev + LPVOID pModData = NULL; // module bytes + DWORD dwErr = ERROR_SUCCESS, // return code + dwModSize; // rsrc byte len + MMRESULT mRes; // waveOut* error + int iRes; // xmplib error + HANDLE hMmEvent = NULL; + + // Multi-buffer drifting +#define BUF_COUNT 3 + LPBYTE lpBufs[BUF_COUNT] = {0}; + WAVEHDR wHdrs[BUF_COUNT] = {0}; + const DWORD dwBufSize = XMP_MAX_FRAMESIZE; + + if (state == NULL) return ERROR_INVALID_PARAMETER; + + hMmEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!hMmEvent) return GetLastError(); + + { + // Generate the buffers + int i; + + for (i = 0; i < BUF_COUNT; i++) { + lpBufs[i] = HeapAlloc(GetProcessHeap(), + 0, + dwBufSize); + if (lpBufs[i] == NULL) { + dwErr = ERROR_NOT_ENOUGH_MEMORY; + goto threadDone; + } + wHdrs[i].lpData = lpBufs[i]; + wHdrs[i].dwBufferLength = dwBufSize; + } + } + + mRes = waveOutOpen(&hwOut, + WAVE_MAPPER, + state->pwfx, + (DWORD_PTR)hMmEvent, + 0, + CALLBACK_EVENT); + if (mRes) return ERROR_INVALID_HANDLE; + + xCtx = xmp_create_context(); + if (!xCtx) { + dwErr = ERROR_BROKEN_PIPE; + goto threadDone; + } + + { + // Find and load the resource. We supposedly don't + // need to free our handles on Win32, so handle it in + // its own block, I guess? + HRSRC hRsrc = FindResource(NULL, + MAKEINTRESOURCE(IDR_BGM), + _T("MUSIC")); + HGLOBAL hModFile = NULL; + if (hRsrc) { + hModFile = LoadResource(NULL, hRsrc); + } + + if (!hModFile) { + dwErr = GetLastError(); + goto threadDone; + } + + dwModSize = SizeofResource(NULL, hRsrc); + if (!dwModSize) { + dwErr = GetLastError(); + goto threadDone; + } + + pModData = LockResource(hModFile); + if (!pModData) { + dwErr = GetLastError(); + goto threadDone; + } + } + + if ((iRes = xmp_load_module_from_memory(xCtx, + pModData, + dwModSize)) != 0) { + dwErr = ERROR_INVALID_DATA; + goto threadDone; + } + + DebugPrintf("Loading mod at %d Hz\n", state->pwfx->nSamplesPerSec); + xmp_start_player(xCtx, + state->pwfx->nSamplesPerSec, + 0); + + // Player frame loop! + { + int iErrCount = 0, // max 5 consecutive errs before + // we give up + iCurBuf = 0; // Current buffer + + BOOL bDone = FALSE; + const HANDLE hEvents[] = { + hMmEvent, + state->hDone, + state->hPause, + }; + +#if _DEBUG + struct xmp_module_info xmi = {0}; + + xmp_get_module_info(xCtx, &xmi); + DebugPrintf("\n== Mod info ==\n" + _T("Speed: %d\n") + _T("BPM: %d\n") + _T("Fmt: %s\n") + _T("== End Mod info ==\n\n"), + xmi.mod->spd, + xmi.mod->bpm, + xmi.mod->type); +#endif /* _DEBUG */ + + while (iErrCount < 5 && !bDone) { + struct xmp_frame_info xfi = {0}; + + // Reset the WAVEHDR + wHdrs[iCurBuf].dwFlags = 0; + wHdrs[iCurBuf].lpData = lpBufs[iCurBuf]; + + // Pull the current audio frame + if (xmp_play_frame(xCtx)) { + dwErr = ERROR_READ_FAULT; + break; + } + + xmp_get_frame_info(xCtx, &xfi); + + memcpy(wHdrs[iCurBuf].lpData, xfi.buffer, xfi.buffer_size); + wHdrs[iCurBuf].dwBufferLength = xfi.buffer_size; + + waveOutPrepareHeader(hwOut, + &wHdrs[iCurBuf], + sizeof(WAVEHDR)); + + // Write it to the audio device + if (waveOutWrite(hwOut, &wHdrs[iCurBuf], sizeof(WAVEHDR))) { + dwErr = ERROR_WRITE_FAULT; + iErrCount++; + } else { + iErrCount = dwErr = 0; + + // Set up the next buffer, or wait for it to complete + iCurBuf = (iCurBuf + 1) % BUF_COUNT; + while (((wHdrs[iCurBuf].dwFlags & WHDR_PREPARED) == WHDR_PREPARED) && + ((wHdrs[iCurBuf].dwFlags & WHDR_DONE) != WHDR_DONE)) { + // Use this opportunity to listen for every event + DWORD dwRes = WaitForMultipleObjects( + sizeof(hEvents) / sizeof(HANDLE), + hEvents, + FALSE, + 1000); + + if (dwRes == WAIT_FAILED) { + HRESULT hrErr = GetLastError(); + DebugPrintf("Agh, got error %08x\n", hrErr); + iErrCount++; + } else if (dwRes == WAIT_OBJECT_0) { + // TODO: should auto-reset, right? + ResetEvent(hMmEvent); + } else if (dwRes == WAIT_OBJECT_0 + 1) { + // state->hDone set, clean up after we're done + bDone = TRUE; + } else if (dwRes == WAIT_OBJECT_0 + 2) { + // state->hPause set, pause or unpause + if (state->bPaused) { + waveOutPause(hwOut); + } else { + waveOutRestart(hwOut); + } + } + } + waveOutUnprepareHeader(hwOut, + &wHdrs[iCurBuf], + sizeof(WAVEHDR)); + } + } + } + +threadDone: + if (xCtx) { + xmp_end_player(xCtx); + xmp_release_module(xCtx); + xmp_free_context(xCtx); + } + + if (hwOut) { + waveOutReset(hwOut); + waveOutClose(hwOut); + } + + { + int i; + for (i = 0; i < BUF_COUNT; i++) { + if (lpBufs[i]) { + if (wHdrs[i].dwFlags & WHDR_PREPARED) { + waveOutUnprepareHeader(hwOut, + &wHdrs[i], + sizeof(WAVEHDR)); + } + HeapFree(GetProcessHeap(), 0, lpBufs[i]); + } + } + } + + ExitThread(dwErr); + return dwErr; +} + +void +EndMusic(BgmState state) +{ + if (!state) return; + + SetEvent(state->hDone); + // Wait for thread to finish, to avoid an audio driver crash + WaitForSingleObject(state->hThread, INFINITE); + + // Clean up + HeapFree(GetProcessHeap(), 0, state->pwfx); + CloseHandle(state->hDone); + CloseHandle(state->hPause); + HeapFree(GetProcessHeap(), 0, state); + + return; +} \ No newline at end of file diff --git a/Keygender32/BGM.h b/Keygender32/BGM.h new file mode 100644 index 0000000..16eef9c --- /dev/null +++ b/Keygender32/BGM.h @@ -0,0 +1,20 @@ +#pragma once + +struct _BgmState; +typedef struct _BgmState *BgmState; + +// Begins playing music. Returns FALSE on error, or TRUE if the music +// thread was able to start. +// +// Note: This function doesn't test for whether the music was able to +// start! There's no way to test for that at the moment. +BOOL PrepareMusic(HINSTANCE, BgmState *); + +// Ends the music thread. +void EndMusic(BgmState); + +// Toggles between play and pause. Returns -1 on error, or the +// current state on success: 0 is playing, 1 is paused. +int TogglePlayPause(BgmState state); + +char *MusicStartFailReason; \ No newline at end of file diff --git a/Keygender32/Debug.c b/Keygender32/Debug.c new file mode 100644 index 0000000..b5a66d9 --- /dev/null +++ b/Keygender32/Debug.c @@ -0,0 +1,21 @@ +#include "stdafx.h" +#include "Debug.h" +#include +#include + +#ifdef _DEBUG +void +_DebugPrintf(LPCTSTR fmt, ...) +{ + va_list args; + TCHAR szBuf[256] = {0}; + + va_start(args, fmt); + + if (SUCCEEDED(_vsntprintf_s(szBuf, 256, 255, fmt, args))) { + OutputDebugString(szBuf); + } + + return; +} +#endif \ No newline at end of file diff --git a/Keygender32/Debug.h b/Keygender32/Debug.h new file mode 100644 index 0000000..3808911 --- /dev/null +++ b/Keygender32/Debug.h @@ -0,0 +1,9 @@ +#pragma once + +#ifdef _DEBUG +#define _AsStr(x) #x +#define DebugPrintf(x, ...) _DebugPrintf(_T(__FUNCTION__) _T(": ") _T(x), __VA_ARGS__) +void _DebugPrintf(LPCTSTR fmt, ...); +#else +#define DebugPrintf(x, ...) +#endif \ No newline at end of file diff --git a/Keygender32/Dialog.c b/Keygender32/Dialog.c new file mode 100644 index 0000000..202aaeb --- /dev/null +++ b/Keygender32/Dialog.c @@ -0,0 +1,391 @@ +#include "stdafx.h" + +#include "Nfo.h" +#include "BGM.h" +#include "Debug.h" +#include "Dialog.h" +#include "Generator.h" +#include "Nfo.h" +#include "resource.h" +#include "Starfield.h" + +#include + + +#define TIMER_SBANIM 0x1 +#define PAUSE_TEXT _T("Pause") +#define PLAY_TEXT _T("Play") +#define WINE_USER_TEXT _T("Hey Wine user! Press F1 for more info.") + +static LPCTSTR PLACEHOLDER_TEXT = _T("they/them, she/her, he/him, etc."); +static LPCTSTR szStatusBarText = _T("Now Playing: Space Debris - Captain"); + +static BOOL bEditFocused = FALSE; +static WNDPROC OldEditWndProc; + +LPCTSTR szBannedWords[] = { + _T("helicopter"), +}; + +static BOOL +UserIsRunningWine(void) +{ + HMODULE hNtdll = GetModuleHandle(_T("ntdll.dll")); + if (hNtdll) { + LPVOID lpWineGetVersion = GetProcAddress(hNtdll, _T("wine_get_version")); + return (lpWineGetVersion != NULL); + } + return FALSE; +} + + +static LRESULT CALLBACK +EditWndProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + /* Oho, this one feels *cursed*. + * + * Here's the general theory: Windows XP provides EM_SETCUEBANNER, + * meaning Windows 2000/Me and below don't have placeholder text. + * Additionally, if your Windows XP is set to a CJK locale, no + * placeholder text for you. + * + * So, let's work around it by implementing our own placeholder! + * What could go wrong? + */ + switch (uMsg) { + case WM_PAINT: + // Let the original proc paint as needed + CallWindowProc(OldEditWndProc, hWnd, uMsg, wParam, lParam); + { + HDC hDC = GetDC(hWnd); + COLORREF crNormal; + TCHAR szInput[8] = {7,0}; + // I don't know if it's okay to just call a WndProc like + // this, but they won't know, right? + LRESULT lResult = CallWindowProc( + OldEditWndProc, + hWnd, + EM_GETLINE, + 0, + (LPARAM)szInput); + + if (!lResult && !bEditFocused) { + RECT rcArea = {0}; + // Get the control font + HFONT hFont = (HFONT)CallWindowProc( + OldEditWndProc, + hWnd, + WM_GETFONT, + 0, + 0), + hOldFont; + hOldFont = SelectObject(hDC, hFont); + + // Get the selection rect, so the placeholder text lines up + CallWindowProc( + OldEditWndProc, + hWnd, + EM_GETRECT, + 0, + (LPARAM)&rcArea); + + // TODO: is GRAYTEXT the correct color? + crNormal = SetTextColor(hDC, + GetSysColor(COLOR_GRAYTEXT)); + DrawText(hDC, + PLACEHOLDER_TEXT, + (int)_tcslen(PLACEHOLDER_TEXT), + &rcArea, + DT_VCENTER | DT_SINGLELINE); + + SelectObject(hDC, hOldFont); + SetTextColor(hDC, crNormal); + } + + DeleteDC(hDC); + + return 0; + } + break; + default: + return CallWindowProc(OldEditWndProc, hWnd, uMsg, wParam, lParam); + } + return 0; +} + + +INT_PTR CALLBACK +MainDlgProc(HWND hDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static int iParts[2]; + static HCURSOR hPointer = NULL; + static BgmState bgmState = NULL; + static LPTSTR szToggleText = NULL; + static RECT rcDialog = {0}; + static COLORREF crLink = 0; + TCHAR szInput[65] = {0}; + static OSVERSIONINFO osver = {sizeof(OSVERSIONINFO),0}; + + switch (uMsg) { + case WM_INITDIALOG: + { + // At least *try* to support Windows <2000 + if (GetVersionEx(&osver)) { + if (osver.dwMajorVersion >= 5) { + // COLOR_HOTLIGHT is only supported in 2k+ + crLink = GetSysColor(26); + } else { + HWND hStarfield = GetDlgItem( + hDlg, + IDC_STARFIELD); + // Borrowing the link color from HTML5 spec + crLink = RGB(0, 0, 0xee); + // Win98 also seems grumpy about the amount of GDI + // rendering, so slow it down a bit + SendMessage(hStarfield, + WMU_FRAMERATE, + 30, + 0); + } + } + } + + { + // Wine doesn't always (ever?) show the [?] button. Give the + // user another way to access it. + if (UserIsRunningWine()) { + szStatusBarText = WINE_USER_TEXT; + } + } + + // initialize static vars + hPointer = LoadCursor(NULL, MAKEINTRESOURCE(32649)); + bgmState = (BgmState)lParam; + szToggleText = PAUSE_TEXT; + OldEditWndProc = (WNDPROC)SetWindowLong( + GetDlgItem(hDlg, IDC_PNTYPE), + GWL_WNDPROC, + (LONG)EditWndProc); + + { + // Set up status bar parts + LONG lDlgWidth = LOWORD(GetDialogBaseUnits()), + lRightWidth = (lDlgWidth * 6); + + GetClientRect(hDlg, &rcDialog); + iParts[0] = rcDialog.right - lRightWidth; + iParts[1] = -1; + + SendDlgItemMessage(hDlg, + IDC_STATUSBAR, + SB_SETPARTS, + 2, + (LPARAM)iParts); + } + + SendDlgItemMessage(hDlg, + IDC_STATUSBAR, + SB_SETTEXT, + SBT_OWNERDRAW | 0, + 0); + SendDlgItemMessage(hDlg, + IDC_STATUSBAR, + SB_SETTEXT, + SBT_OWNERDRAW | 1, + 0); + break; + + case WM_SYSCOMMAND: + if (wParam == SC_CONTEXTHELP) { + DialogBox( + GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_ABOUT), + hDlg, + NfoDlgProc); + return TRUE; + } else { + return FALSE; + } + break; + + case WM_HELP: + DialogBox( + GetModuleHandle(NULL), + MAKEINTRESOURCE(IDD_ABOUT), + hDlg, + NfoDlgProc); + return TRUE; + + case WM_DRAWITEM: + if (wParam == IDC_STATUSBAR) { + LPDRAWITEMSTRUCT lpDraw = (LPDRAWITEMSTRUCT)lParam; + HFONT hFont = (HFONT)SendMessage( + lpDraw->hwndItem, + WM_GETFONT, + (WPARAM)0, + (LPARAM)0); + int iOldBkMode = SetBkMode(lpDraw->hDC, TRANSPARENT); + + if (lpDraw->itemID == 0) { + // Draw the status bar text + DrawText( + lpDraw->hDC, + szStatusBarText, + -1, + &lpDraw->rcItem, + DT_VCENTER | DT_SINGLELINE); + + } else if (lpDraw->itemID == 1) { + // Draw the Play/Pause "link" + HFONT hLinkFont, hOldFont; + LOGFONT lf; + COLORREF crOldColor; + + GetObject(hFont, sizeof(lf), &lf); + lf.lfUnderline = TRUE; + + hLinkFont = CreateFontIndirect(&lf); + hOldFont = SelectObject(lpDraw->hDC, hLinkFont); + + crOldColor = SetTextColor(lpDraw->hDC, crLink); + + DrawText(lpDraw->hDC, + szToggleText, + -1, + &lpDraw->rcItem, + DT_CENTER | DT_VCENTER | DT_SINGLELINE); + + // put everything back how we found it + SelectObject(lpDraw->hDC, hOldFont); + SetTextColor(lpDraw->hDC, crOldColor); + + DeleteObject(hLinkFont); + } + SetBkMode(lpDraw->hDC, iOldBkMode); + } + break; + + case WM_NOTIFY: + if (wParam == IDC_STATUSBAR) { + LPNMMOUSE lpnm = (LPNMMOUSE)lParam; + if (lpnm->hdr.code == NM_CLICK && + lpnm->dwItemSpec == 1) { + // Play/Pause "link" + switch (TogglePlayPause(bgmState)) { + case 0: + szToggleText = PAUSE_TEXT; + break; + case 1: + szToggleText = PLAY_TEXT; + break; + } + + SendDlgItemMessage(hDlg, + IDC_STATUSBAR, + SB_SETTEXT, + SBT_OWNERDRAW | 1, + 0); + + // Make the border dynamic, like the original + iParts[0] = (rcDialog.right - rcDialog.left) - + (LOWORD(GetDialogBaseUnits()) * (int)_tcslen(szToggleText)); + SendDlgItemMessage(hDlg, + IDC_STATUSBAR, + SB_SETPARTS, + 2, + (LPARAM)iParts); + } + } + break; + + case WM_SETCURSOR: + if ((HWND)wParam == GetDlgItem(hDlg, IDC_STATUSBAR)) { + // Make the Play/Pause link act like a link + POINT ptCur; + GetCursorPos(&ptCur); + if (ScreenToClient(hDlg, &ptCur) && + ptCur.x >= iParts[0]) { + SetCursor(hPointer); + SetWindowLong(hDlg, DWL_MSGRESULT, TRUE); + return TRUE; + } + } + break; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) { + // Generate button pressed + LRESULT lResult; + TCHAR szKeyOut[19] = {0}; + szInput[0] = 64; + lResult = SendDlgItemMessage( + hDlg, + IDC_PNTYPE, + EM_GETLINE, + 0, + (LPARAM)szInput); + if (!lResult) break; + + if (GenerateKey(szInput, szKeyOut)) { + SendDlgItemMessage(hDlg, + IDC_KEYDATA, + WM_SETTEXT, + 0, + (LPARAM)szKeyOut); + } + } else if (LOWORD(wParam) == IDC_PNTYPE) { + // Pro Nouns edition edit control + if (HIWORD(wParam) == EN_UPDATE) { + int i; + BOOL bEnable = TRUE; + LRESULT lResult; + szInput[0] = 64; + lResult = SendDlgItemMessage( + hDlg, + IDC_PNTYPE, + EM_GETLINE, + 0, + (LPARAM)szInput); + if (!lResult) { + bEnable = FALSE; + } else { + // Handle word validation + for (i = 0; i < (sizeof(szBannedWords) / sizeof(szBannedWords[0])); i++) { + int j, x = 0, iWordLen = (int)_tcslen(szBannedWords[i]); + + for (j = 0; j < (int)_tcslen(szInput); j++) { + if (iswalpha(szInput[j]) && (towlower(szInput[j]) == szBannedWords[i][x])) { + if (++x >= iWordLen) { + bEnable = FALSE; + break; + } + } + } + } + } + + EnableWindow(GetDlgItem(hDlg, IDOK), bEnable); + } else if (HIWORD(wParam) == EN_SETFOCUS) { + // edit control focused, don't show the placeholder + bEditFocused = TRUE; + } else if (HIWORD(wParam) == EN_KILLFOCUS) { + bEditFocused = FALSE; + } + } + break; + + case WM_CLOSE: + EndDialog(hDlg, 0); + break; + + default: + return FALSE; + } + return TRUE; +} \ No newline at end of file diff --git a/Keygender32/Dialog.h b/Keygender32/Dialog.h new file mode 100644 index 0000000..b8a3d38 --- /dev/null +++ b/Keygender32/Dialog.h @@ -0,0 +1,3 @@ +#pragma once + +INT_PTR CALLBACK MainDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/Keygender32/Generator.c b/Keygender32/Generator.c new file mode 100644 index 0000000..2af1bfa --- /dev/null +++ b/Keygender32/Generator.c @@ -0,0 +1,116 @@ +#include "stdafx.h" +#include "Random.h" +#include "Generator.h" +#include + +static const TCHAR szBaseChars[] = _T("BCDFGHJKMPQRTVWXY346789"); +static const BYTE base = (sizeof(szBaseChars) / sizeof(TCHAR)) - 1; +static const UINT64 uPrivKey[] = { 0x0a0d212073, 0x7468676972, 0x20736e617274 }; + +// Create an Adler32 checksum according to the provided szInput. +static DWORD +ck_adler32(LPCTSTR szInput, + DWORD dwLen) +{ + DWORD a = 1, + b = 0, + i; + + for (i = 0; i < dwLen; i++) { + // XXX: This is a really naive way to "convert" to ANSI + a += szInput[i] & 0xff; + b += a; + } + + a %= 65521; + b %= 65521; + + return ((b << 16) | a); +} + +// Encode a number as a "sanitized Microsoft" base-23 string +static BOOL +EncodeNumber(LPVOID lpIn, + DWORD dwSize, + LPTSTR szOut) +{ + UINT64 uNum = 0; + TCHAR *ptr = szOut + 5; + + if (!lpIn || !szOut) return FALSE; + + if (dwSize > 8) return FALSE; + + // XXX: Win32 is always little endian, so should be fine? + CopyMemory(&uNum, lpIn, dwSize); + + *(ptr + 1) = 0; + do { + *ptr-- = szBaseChars[uNum % base]; + uNum /= base; + } while (ptr >= szOut); + + return TRUE; +} + +BOOL +GenerateKey(LPCTSTR szInput, + LPTSTR szOut) +{ + /* In the original implementation, this just generated random + * "digits." I went too far with the bit, so now the "keys" have + * some procedural generation! They're still structured similarly: + * + * XXXXX-YYYYY-ZZZZZ + * + * XXXXX is a random DWORD (shifted right 2 bytes to look more + * random) and XORed by the first private key QWORD. + * YYYYY is an Adler32 checksum of the user input, XORed by the + * second private key QWORD. + * Finally, ZZZZZ is the Adler32 checksum of "XXXXX-YYYYY", XORed + * by the third private key QWORD. + */ + static BOOL bSeeded = FALSE; + UINT64 uRandom; + UINT64 dwChecksum, dwFinalSum; + LPTSTR szPtr = szOut; + + + if (!szInput || !szOut) return FALSE; + + if (!bSeeded) { + xorsrand((unsigned)time(NULL)); + bSeeded = TRUE; + } + + // generate segment one + uRandom = ((xorrand() & 0xffff) << 16) ^ uPrivKey[0]; + if (!EncodeNumber(&uRandom, sizeof(UINT64), szPtr)) { + return FALSE; + } + + szPtr += 5; + + *szPtr++ = _T('-'); + + // ... and segment 2 + dwChecksum = ck_adler32(szInput, (DWORD)_tcslen(szInput)) ^ + uPrivKey[1]; + if (!EncodeNumber(&dwChecksum, sizeof(DWORD), szPtr)) { + return FALSE; + } + + szPtr += 5; + *szPtr++ = _T('-'); + + // ... finally, segment 3 + dwFinalSum = ck_adler32(szOut, 11) ^ uPrivKey[2]; + if (!EncodeNumber(&dwFinalSum, sizeof(DWORD), szPtr)) { + return FALSE; + } + + szPtr += 5; + *szPtr = 0; + + return TRUE; +} \ No newline at end of file diff --git a/Keygender32/Generator.h b/Keygender32/Generator.h new file mode 100644 index 0000000..4f37f75 --- /dev/null +++ b/Keygender32/Generator.h @@ -0,0 +1,6 @@ +#pragma once + +// Generate a key using szInput, feeding the output into szOut. +// +// NOTE: szOut must be at least 18 TCHARs! +BOOL GenerateKey(LPCTSTR szInput, LPTSTR szOut); \ No newline at end of file diff --git a/Keygender32/Keygender32.c b/Keygender32/Keygender32.c new file mode 100644 index 0000000..37d2eaf --- /dev/null +++ b/Keygender32/Keygender32.c @@ -0,0 +1,43 @@ +// Keygender32.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" +#include "Keygender32.h" +#include + +#define MAX_LOADSTRING 100 + +int APIENTRY _tWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + BgmState state = NULL; + + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + + setlocale( LC_ALL, ".437" ); + + InitCommonControls(); + InitStarfieldControl(hInstance); + + if (!PrepareMusic(hInstance, &state)) { + MessageBoxA( + NULL, + MusicStartFailReason, + "Music play failed ;_;", + MB_OK | MB_ICONERROR); + } + + DialogBoxParam(hInstance, + MAKEINTRESOURCE(IDD_MAIN), + NULL, + MainDlgProc, + (LPARAM)state); + + EndMusic(state); + DeinitStarfieldControl(hInstance); + + return 0; +} \ No newline at end of file diff --git a/Keygender32/Keygender32.h b/Keygender32/Keygender32.h new file mode 100644 index 0000000..94c82ee --- /dev/null +++ b/Keygender32/Keygender32.h @@ -0,0 +1,7 @@ +#pragma once + +#include "resource.h" +#include "Starfield.h" +#include "Dialog.h" +#include "BGM.h" +#include "Debug.h" \ No newline at end of file diff --git a/Keygender32/Keygender32.rc b/Keygender32/Keygender32.rc new file mode 100644 index 0000000..93710d7 --- /dev/null +++ b/Keygender32/Keygender32.rc @@ -0,0 +1,217 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MAIN DIALOGEX 0, 0, 227, 135 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CONTEXTHELP +CAPTION "Pro Nouns Keygenderator" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_STARFIELD,"Starfield",WS_TABSTOP,7,7,213,51 + LTEXT "Which version of Pro Nouns do you want to use?",IDC_STATIC,7,65,156,10 + EDITTEXT IDC_PNTYPE,7,81,213,14,ES_AUTOHSCROLL + PUSHBUTTON "Generate Key",IDOK,155,99,65,14,WS_DISABLED + EDITTEXT IDC_KEYDATA,54,99,94,14,ES_AUTOHSCROLL | ES_READONLY + LTEXT "License Key:",IDC_STATIC,7,99,41,14,SS_CENTERIMAGE + CONTROL "",IDC_STATUSBAR,"msctls_statusbar32",WS_TABSTOP,7,114,50,14 +END + +IDD_ABOUT DIALOGEX 0, 0, 235, 177 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION +EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW +CAPTION "About" +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + GROUPBOX "Credits",IDC_STATIC,7,7,221,98,BS_CENTER + LTEXT "This is a port of the JavaScript version, by Luna (https://tiredand.gay).",IDC_STATIC,13,16,209,18 + LTEXT "This software uses libXMP, which is Copyright c 1996-2023 Claudio Matsuoka and Hipolito Carraro Jr. See the NFO for more info.",IDC_STATIC,13,40,209,25 + LTEXT "Background music is ""Space Debris"" by Captain.",IDC_STATIC,13,71,209,8 + PUSHBUTTON "Original Keygender",IDC_OGLINK,148,85,74,14 + GROUPBOX "Misc Greets",IDC_STATIC,7,111,221,40,BS_CENTER + CTEXT "lifning - iliana - Hell Labs",IDC_STATIC,13,120,209,25,SS_CENTERIMAGE + PUSHBUTTON "Close",IDCLOSE,178,156,50,14 + PUSHBUTTON "Hell Labs @ Cohost",IDC_HLSITE,103,156,70,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_MAIN, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 220 + VERTGUIDE, 48 + VERTGUIDE, 54 + VERTGUIDE, 148 + VERTGUIDE, 155 + TOPMARGIN, 7 + BOTTOMMARGIN, 128 + HORZGUIDE, 58 + HORZGUIDE, 65 + HORZGUIDE, 75 + HORZGUIDE, 81 + HORZGUIDE, 95 + HORZGUIDE, 99 + HORZGUIDE, 113 + END + + IDD_ABOUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + VERTGUIDE, 13 + VERTGUIDE, 142 + VERTGUIDE, 148 + VERTGUIDE, 172 + VERTGUIDE, 178 + VERTGUIDE, 222 + TOPMARGIN, 7 + BOTTOMMARGIN, 170 + HORZGUIDE, 16 + HORZGUIDE, 34 + HORZGUIDE, 40 + HORZGUIDE, 65 + HORZGUIDE, 71 + HORZGUIDE, 79 + HORZGUIDE, 85 + HORZGUIDE, 99 + HORZGUIDE, 105 + HORZGUIDE, 111 + HORZGUIDE, 120 + HORZGUIDE, 145 + HORZGUIDE, 151 + HORZGUIDE, 157 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// MUSIC +// + +IDR_BGM MUSIC "space_debris.mod" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Hell Labs" + VALUE "FileDescription", "Pro Nouns Keygenderator" + VALUE "FileVersion", "1, 0, 0, 0" + VALUE "InternalName", "Keygender" + VALUE "OriginalFilename", "Keygendr.exe" + VALUE "ProductName", "Pro Nouns Keygender" + VALUE "ProductVersion", "1, 0, 0, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_KEYGENDER ICON "keygender.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Keygender32/Keygender32.vcproj b/Keygender32/Keygender32.vcproj new file mode 100644 index 0000000..f5d096f --- /dev/null +++ b/Keygender32/Keygender32.vcproj @@ -0,0 +1,505 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Keygender32/Nfo.c b/Keygender32/Nfo.c new file mode 100644 index 0000000..ad32605 --- /dev/null +++ b/Keygender32/Nfo.c @@ -0,0 +1,43 @@ +#include "stdafx.h" +#include "Nfo.h" +#include "resource.h" +#include + +#define OpenURL(url) \ + ShellExecute( \ + hDlg, \ + _T("open"), \ + url, \ + NULL, \ + NULL, \ + SW_SHOWNORMAL) + +INT_PTR CALLBACK +NfoDlgProc(HWND hDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) { + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_HLSITE: + OpenURL(_T("https://cohost.org/hell-labs")); + break; + case IDC_OGLINK: + OpenURL(_T("https://tiredand.gay/keygender/")); + break; + case IDCLOSE: + EndDialog(hDlg, 0); + break; + } + break; + case WM_CLOSE: + EndDialog(hDlg, 0); + break; + default: + return FALSE; + } + + return TRUE; +} \ No newline at end of file diff --git a/Keygender32/Nfo.h b/Keygender32/Nfo.h new file mode 100644 index 0000000..20da962 --- /dev/null +++ b/Keygender32/Nfo.h @@ -0,0 +1,4 @@ +#pragma once + +INT_PTR CALLBACK +NfoDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); \ No newline at end of file diff --git a/Keygender32/Random.c b/Keygender32/Random.c new file mode 100644 index 0000000..4f1269f --- /dev/null +++ b/Keygender32/Random.c @@ -0,0 +1,45 @@ +#include "stdafx.h" +#include "Random.h" + +/* From https://prng.di.unimi.it/xoshiro256plusplus.c */ + +static UINT64 s[4]; + +static __inline UINT64 +rotl(const UINT64 x, int k) +{ + return (x << k) | (x >> (64 - k)); +} + +void +xorsrand(unsigned int seed) +{ + UINT64 x = seed; + int i; + + for (i = 0; i < 4; i++) { + UINT64 z = (x += 0x9E3779B97F4A7C15ULL); + z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL; + z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL; + s[i] = x = z ^ (z >> 31); + } +} + +UINT64 +xorrand(void) +{ + const UINT64 result = rotl(s[0] + s[3], 23) + s[0]; + + const UINT64 t = s[1] << 17; + + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + + s[2] ^= t; + + s[3] = rotl(s[3], 45); + + return result; +} \ No newline at end of file diff --git a/Keygender32/Random.h b/Keygender32/Random.h new file mode 100644 index 0000000..89e5376 --- /dev/null +++ b/Keygender32/Random.h @@ -0,0 +1,7 @@ +#pragma once + +// Provides a seed for xorrand(). +void xorsrand(unsigned int seed); +// Generates a random UINT64 according to the xoshiro256++ PRNG +// algorithm. +UINT64 xorrand(void); \ No newline at end of file diff --git a/Keygender32/Starfield.c b/Keygender32/Starfield.c new file mode 100644 index 0000000..47e52b2 --- /dev/null +++ b/Keygender32/Starfield.c @@ -0,0 +1,308 @@ +#include "stdafx.h" +#include "Starfield.h" +#include "Random.h" + +#include +#include + +#define WMU_FRAMERATE_NAME _T("SetFramerate_{6CFC2304-CE89-40c4-881C-988D36FBB978}") +#define DENSITY 3 +#define LAYERS 5 + +const COLORREF crTransColors[] = { + RGB(0x5b, 0xce, 0xfa), + RGB(0xf5, 0xa9, 0xb8), + RGB(0xff, 0xff, 0xff), +}; + +typedef struct _StarLayer { + HBITMAP hbmFrame; + DOUBLE x; + BYTE alpha; +} StarLayer; + +typedef struct _StarState { + StarLayer layers[LAYERS]; + HBITMAP hbmColors[3]; // for each stripe + HDC hMemDC; // blits to screen + HDC hBlitDC; // blits to hMemDC +} StarState; + +static void +DeleteState(StarState *state) +{ + if (state) { + int i; + + if (state->hBlitDC) DeleteDC(state->hBlitDC); + if (state->hMemDC) DeleteDC(state->hMemDC); + + for (i = 0; i < LAYERS; i++) { + if (state->layers[i].hbmFrame) { + DeleteObject(state->layers[i].hbmFrame); + } + } + + for (i = 0; i < 3; i++) { + if (state->hbmColors[i]) DeleteObject(state->hbmColors[i]); + } + + // The state is usually stored in the stack, so zero out any + // values that might cause issues in case of reuse + ZeroMemory(state, sizeof(StarState)); + } +} + +// Initializes the StarState based on the given client area RECT +static void +InitState(HDC hDC, + StarState *state, + LPRECT rcArea) +{ + UINT i, // iterators + iStripeSplit; // height per stripe + HBITMAP hbmColors[3]; + DWORD dwStarCount = rcArea->bottom * DENSITY; + + iStripeSplit = rcArea->bottom / 5; + + // init DCs + state->hMemDC = CreateCompatibleDC(hDC); + state->hBlitDC = CreateCompatibleDC(hDC); + + // init layer bitmaps + for (i = 0; i < LAYERS; i++) { + HBITMAP hbmOrig; + state->layers[i].hbmFrame = CreateCompatibleBitmap(hDC, + rcArea->right, + rcArea->bottom); + state->layers[i].x = 0; + state->layers[i].alpha = 159 + (i * 24); + + // Before stars, fill the frame with the void of space + hbmOrig = SelectObject( + state->hBlitDC, + state->layers[i].hbmFrame); + BitBlt(state->hBlitDC, + 0, 0, + rcArea->right, rcArea->bottom, + NULL, + 0, 0, + BLACKNESS); + SelectObject( + state->hBlitDC, + hbmOrig); + } + + // we only need to init the stripes, thanks to AlphaBlend + for (i = 0; i < 3; i++) { + HBITMAP hbmOrig; + + hbmColors[i] = CreateCompatibleBitmap(hDC, 1, 1); + hbmOrig = SelectObject(state->hBlitDC, + hbmColors[i]); + SetPixel(state->hBlitDC, + 0, 0, crTransColors[i]); + SelectObject(state->hBlitDC, hbmOrig); + } + + // arm the RNG + xorsrand((unsigned)time(NULL)); + + // create each star, AlphaBlending as we go for ideal effect + for (i = 0; i < dwStarCount; i++) { + int layer = (WORD)(xorrand() >> 48) % LAYERS, + x = (int)((WORD)xorrand()) % (rcArea->right - 4), + y = i / DENSITY, + stripe = y / iStripeSplit, + width = max((int)(((float)layer + 3.0f) / 2.0f), 1); + + HBITMAP hbmColor = hbmColors[(stripe < 3) ? stripe : + (stripe == 3) ? 1 : 0], + hbmOrig, + hbmBlitOrig; + + BLENDFUNCTION bf = { + AC_SRC_OVER, + 0, + state->layers[layer].alpha, + 0 + }; + + hbmOrig = SelectObject(state->hMemDC, state->layers[layer].hbmFrame); + hbmBlitOrig = SelectObject(state->hBlitDC, hbmColor); + AlphaBlend(state->hMemDC, + x - (width / 2), y - (width / 2), + width, width, + state->hBlitDC, + 0, 0, + 1, 1, + bf); + + if (x + width > rcArea->right) { + // loop around to make the square look complete + AlphaBlend(state->hMemDC, + 0, y, + (x + width) - rcArea->right, width, + state->hBlitDC, + 0, 0, + 1, 1, + bf); + } + + SelectObject(state->hBlitDC, hbmBlitOrig); + SelectObject(state->hMemDC, hbmOrig); + } + + for (i = 0; i < 3; i++) { + DeleteObject(hbmColors[i]); + } + + return; +} + +static void +DrawStars(HDC hDC, + StarState *state, + LPRECT rcArea) +{ + // Logic taken from https://github.com/lunasorcery/keygender/blob/main/script.js + UINT i; + HBITMAP hbmOrig, + hbmFrame = CreateCompatibleBitmap(hDC, + rcArea->right, + rcArea->bottom); + static DWORD dwLastRun = 0; + DOUBLE dSpeedMult = 1.0; + + hbmOrig = SelectObject(state->hMemDC, hbmFrame); + // Without this, Win98 starts blitting VRAM to our control + BitBlt(state->hMemDC, + 0, 0, + rcArea->right, rcArea->bottom, + NULL, + 0, 0, + BLACKNESS); + + // try to keep a consistent speed across frames + if (dwLastRun != 0) { + DWORD dwElapsed = GetTickCount() - dwLastRun; + dSpeedMult = max(1.0, (dwElapsed / 17.0)); + } + dwLastRun = GetTickCount(); + + for (i = 0; i < LAYERS; i++) { + HBITMAP hbmBlitOrig = NULL; + + // split each layer into two pieces, and stitch them together + int widths[2]; + widths[0] = (int)state->layers[i].x + rcArea->right; + widths[1] = rcArea->right - widths[0]; + + hbmBlitOrig = SelectObject(state->hBlitDC, state->layers[i].hbmFrame); + // Left side of the split + TransparentBlt(state->hMemDC, + 0, 0, + widths[0], rcArea->bottom, + state->hBlitDC, + widths[1], 0, + widths[0], rcArea->bottom, + 0); + // Right side of the split + TransparentBlt(state->hMemDC, + widths[0], 0, + widths[1], rcArea->bottom, + state->hBlitDC, + 0, 0, + widths[1], rcArea->bottom, + 0); + SelectObject(state->hBlitDC, hbmBlitOrig); + + // Update frame location + state->layers[i].x -= ((DOUBLE)i + 1.5) * dSpeedMult; + if (state->layers[i].x + rcArea->right < 0) { + state->layers[i].x += rcArea->right; + } + } + + BitBlt(hDC, + rcArea->left, + rcArea->top, + rcArea->right, + rcArea->bottom, + state->hMemDC, + 0, 0, + SRCCOPY); + + SelectObject(state->hMemDC, hbmOrig); + DeleteObject(hbmFrame); + + return; +} + +static LRESULT CALLBACK +StarfieldWndProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + static RECT rcClient = {0}; + static StarState state = {0}; + static HBITMAP hbmColors[3] = {0}; + static HDC hDC = NULL; + // Default to 60fps + static DOUBLE fFrameRate = (1.0 / 60) * + 1000.0; + + switch (uMsg) { + case WM_CREATE: + hDC = GetDC(hWnd); + + GetClientRect(hWnd, &rcClient); + InitState(hDC, &state, &rcClient); + /* PASSTHRU */ + case WM_TIMER: + // Frame tick! + DrawStars(hDC, &state, &rcClient); + SetTimer(hWnd, 0x69, fFrameRate, NULL); + break; + + case WM_DESTROY: + DeleteState(&state); + DeleteDC(hDC); + hDC = NULL; + break; + + default: + if (uMsg == WMU_FRAMERATE) { + // Update our frame rate + fFrameRate = (1.0 / (DOUBLE)(LONG)wParam) + * 1000.0; + return 0; + } else { + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + } + + return 0; +} + +void +InitStarfieldControl(HINSTANCE hInst) +{ + WNDCLASSEX wcex = {0}; + wcex.cbSize = sizeof(wcex); + wcex.lpfnWndProc = StarfieldWndProc; + wcex.hInstance = hInst; + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.lpszClassName = STARFIELD_CLASS; + RegisterClassEx(&wcex); + + WMU_FRAMERATE = RegisterWindowMessage(WMU_FRAMERATE_NAME); +} + +void +DeinitStarfieldControl(HINSTANCE hInst) +{ + UnregisterClass(STARFIELD_CLASS, hInst); +} \ No newline at end of file diff --git a/Keygender32/Starfield.h b/Keygender32/Starfield.h new file mode 100644 index 0000000..75e524d --- /dev/null +++ b/Keygender32/Starfield.h @@ -0,0 +1,14 @@ +#pragma once + +#define STARFIELD_CLASS _T("Starfield") + +// Initializes the Starfield control. This is required before creating +// a Starfield control using STARFIELD_CLASS. +void InitStarfieldControl(HINSTANCE); + +// Removes the Starfield control class. +void DeinitStarfieldControl(HINSTANCE); + +// Defined by InitStarFieldControl. Send this message to define the +// rough framerate the control tries to render at. +UINT WMU_FRAMERATE; \ No newline at end of file diff --git a/Keygender32/keygender.ico b/Keygender32/keygender.ico new file mode 100644 index 0000000..0f6da89 Binary files /dev/null and b/Keygender32/keygender.ico differ diff --git a/Keygender32/resource.h b/Keygender32/resource.h new file mode 100644 index 0000000..07856dd --- /dev/null +++ b/Keygender32/resource.h @@ -0,0 +1,35 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Keygender32.rc +// +#define IDD_KEYGENDER32_DIALOG 102 +#define IDM_ABOUT 104 +#define IDD_ABOUT 107 +#define IDR_MAINFRAME 128 +#define IDD_MAIN 129 +#define IDR_BGM 132 +#define IDI_KEYGENDER 134 +#define IDR_TTF1 138 +#define IDC_CUSTOM1 1002 +#define IDC_STARFIELD 1002 +#define IDC_PNTYPE 1003 +#define IDC_GENBTN 1004 +#define IDC_KEYDATA 1005 +#define IDC_STATUSBAR 1006 +#define IDC_NFOEDIT 1008 +#define IDC_RICHEDIT21 1009 +#define IDC_OGLINK 1011 +#define IDC_HLSITE 1014 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 139 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1015 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/Keygender32/space_debris.mod b/Keygender32/space_debris.mod new file mode 100644 index 0000000..141cdd6 Binary files /dev/null and b/Keygender32/space_debris.mod differ diff --git a/Keygender32/stdafx.c b/Keygender32/stdafx.c new file mode 100644 index 0000000..47159e2 --- /dev/null +++ b/Keygender32/stdafx.c @@ -0,0 +1,12 @@ +// stdafx.cpp : source file that includes just the standard includes +// Keygender32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file +#pragma comment(linker,"\"/manifestdependency:type='win32' \ + name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ + processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \ + language='*'\"") \ No newline at end of file diff --git a/Keygender32/stdafx.h b/Keygender32/stdafx.h new file mode 100644 index 0000000..5fe6e22 --- /dev/null +++ b/Keygender32/stdafx.h @@ -0,0 +1,35 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0410 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +// Windows Header Files: +#include +#include +#include + +// C RunTime Header Files +#include +#include +#include +#include \ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 0000000..06a8b0f --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,52 @@ + =========================== + BIG BILL HELL'S LICENSE + =========================== + + FUCK YOU, OPEN-SOURCE! + +If you're dumb enough to want to copy this software, you're a big enough +schmuck to abide by BIG BILL HELL'S LICENSE (BBHL): + +| 1. BAD TERMS +| 2. CODE THAT BREAKS DOWN +| 3. THIEVES + +-------------- + 1. BAD TERMS +-------------- + +If you think you're going to find permissive terms in BIG BILL'S, you can +kiss my ASS. It's our belief that you're such a stupid motherfucker, +you'll depend on this bullshit, GUARANTEED. If you make a derivative work: +Shove it up your ugly ASS. You heard us right: Shove it up your ugly ASS. + +-------------------------- + 2. CODE THAT BREAKS DOWN +-------------------------- + +Bring your CHANGE; bring your REPRO; bring your SPOUSE--we'll fuck them! +That's right, we'll fuck your SPOUSE. Because under the BBHL, you're fucked +six ways from Sunday. + +------------ + 3. THIEVES +------------ + +Make a hack with BBHL, home of CHALLENGE GITTING. That's right: + + 3.a. CHALLENGE GITTING + ---------------------- + How does it work? If you submit six PRs straight into main that don't need + feedback, you get no Contributor License Agreement (CLA). + + +DON'T SELL; DON'T DISTRIBUTE; DON'T FORK FROM US, OR WE'LL RIP YOUR BITS OFF. + +ONLY WITH BBHL: THE ONLY LICENSE THAT TELLS YOU TO FUCK OFF. + +HURRY UP, ASSHOLE, THESE TERMS TAKE EFFECT THE MINUTE YOU WRITE A LINE OF +CODE, AND IT BETTER NOT BREAK, OR YOU'RE A DEAD MOTHERFUCKER. + +GO TO HELL. BIG BILL HELL'S LICENSE: OPEN-SOURCE'S FILTHIEST AND EXCLUSIVE +TERMS OF THE MEANEST (SONS OF) BITCHES IN THE WHOLE COMMUNITY, GUARANTEED. + diff --git a/README.TXT b/README.TXT new file mode 120000 index 0000000..4186b11 --- /dev/null +++ b/README.TXT @@ -0,0 +1 @@ +keygendr.for.win32.HL.utf8.NFO \ No newline at end of file diff --git a/keygendr.for.win32.HL.NFO b/keygendr.for.win32.HL.NFO new file mode 100644 index 0000000..4b77172 --- /dev/null +++ b/keygendr.for.win32.HL.NFO @@ -0,0 +1,148 @@ + + ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ + ÜÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜÜ + ÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜ + ÜÛÛÛÛÛÛÛÛÛÛÛÛßßßßßßßßßßßßßßßÛÛÛÛÛÛÛÛÛÛÛÛÜ + ÜÛÛÛÛÛÛÛÛÛßß ßßÛÛÛÛÛÛÛÛÛÜ + ÜÛÛÛÛÛÛÛÛß Ü Ü ßÛÛÛÛÛÛÛÛÜ + ÛÛÛÛÛÛÛÛß ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ßÛÛÛÛÛÛÛÛ + ÛÛÛÛÛÛÛß ÜÛÛÛÛÛÛÛÛÛÛÜ ÜÛÛÛÛÛÛÛÛÛÛÜ ßÛÛÛÛÛÛÛ + ÛÛÛÛÛÛÛß ÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜ ÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛ + ÜÛÛÛÛÛÛ ÛÛÛÛÛÛßÛÛÛÛÛÛÛÛÜÛÛÛÛÛÛÛÛßÛÛÛÛÛÛ ÛÛÛÛÛÛÜ + ÛÛÛÛÛÛ ßÛÛÛÛÛÜ ßÛÛÛÛÛÛÛÛÛÛÛÛÛß ÜÛÛÛÛÛß ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛÛÛÛÛÜ ÛÛÛÛÛÛ ÛÛÛÛÛÛ + ÜÛÛÛÛÛß ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛß ßÛÛÛÛÛÜ + ÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛßßßÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛÛÛß ßÛÛÛÛÛÛÛÛÛÜ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛÛÛÛß ßÛÛÛÛÛÛÛÛÛÛÜ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÜÜÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÜÜ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛÛÛß ÛÛÛÛÛÛ ÛÛÛÛÛÛ ßÛÛÛÛÛÛÛÛÛÜ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÛÛÛÛÛÛÛß ÛÛÛÛÛÛ ÛÛÛÛÛÛ *hl*ßÛÛÛÛÛÛÛ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛ + ÛÛÛÛÛÛ ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ ÛÛÛÛÛÛ + ßÛÛÛÛÛÜ ßßßßßßßßßßßßÛÛÛÛÛÛ ÛÛÛÛÛÛßßßßßßßßßßßß ÜÛÛÛÛÛß + ÛÛÛÛÛÛÜ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÜÛÛÛÛÛÛ + ÛÛÛÛÛÛÜ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÜÛÛÛÛÛÛ + ßÛÛÛÛÛÛÛ ßÛÛÛÛÛÜÛÛÛÛÛß ÜÛÛÛÛÛÛß + ßÛÛÛÛÛÛÛÜ ÛÛÛÛÛÛÛÛÛÛÛ ÜÛÛÛÛÛÛÛß + ßÛÛÛÛÛÛÛÜ ßÛÛÛÛÛÛÛÛÛß ÜÛÛÛÛÛÛÛÛ + ßÛÛÛÛÛÛÛÜÜ ßÛÛÛÛÛÛÛß ÜÜÛÛÛÛÛÛÛÛß + ßÛÛÛÛÛÛÛÛÛÜÜÜ ÜÜÜÛÛÛÛÛÛÛÛÛÛß + ßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛßß + ßßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛßß + ßßßÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛßßß + + + ŞÛİ ŞÛİ ŞÛİŞÛİ ÛÛ ÛÛ + ŞÛİ ŞÛİ ÜÜÜÜ ŞÛİŞÛİ ÛÛ ÜÜÜÜÜ ÛÛ ÜÜÜ ÜÜÜÜÜ + ŞÛÛÛÛÛÛÛİÜÛÛßßÛÛÜŞÛİŞÛİ ÛÛ ÛÛßßßÛİ ÛÛÛßßÛÛÜ ÛÛßßßÛÛ + ŞÛİ ŞÛİÛÛÜÜÜÜÛÛŞÛİŞÛİ ÛÛ ÜÜÛÛÛİ ÛÛ ÛÛ ßÛÛÛÜÜ + ŞÛİ ŞÛİÛÛÜ ÜÜŞÛİŞÛİ ÛÛ ÛÛß ÜÛİ ÛÛÜ ÜÛÛ ÜÜ ßßÛÛ + ŞÛİ ŞÛİ ßÛÛÛÛß ŞÛİŞÛİ ÛÛÛÛÛİßÛÛÛßÛÛİÛÛßÛÛÛß ßÛÛÛÛÛß + + +úÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛú +úÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛú +ú ú +:±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±: +­±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±­ +³ ³ +ÃÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ´ +± Û PRO NOUNS KEYGENDERATOR FOR WINDOWS Û ± +± ÛÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ ± +± Û developer...: [ flurry ] Û name.....: [ keygendr.exe ] Û ± +± Û tester......: [ LiFFY ] Û OS.......: [ WinAll ] Û ± +± Û release date: [ 17 mar 2024 ] Û disks....: [ 01 x 1.44 ] Û ± +± Û Û Û ± +± Û ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» Û Û ± +± ÛÄÄÄşºº RELEASE INFO ººşÄÄÄÄÄÄÄÄÄĞÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ ± +± Û ÈÍÍÍÍÍÍÍÍÍÍÍÍÍͼ Û ± +± Û Û ± +± Û This is a port of the JavaScript version, by Luna. Check out Û ± +± Û her version here: Û ± +± Û Û ± +± Û http://tiredand.gay/keygender/ Û ± +± Û Û ± +± Û This program should be compatible with Windows 2000 and up. Û ± +± Û You might be able to run this on Windows 9x, but beware: when Û ± +± Û we tested it, the system struggled to keep up! It's best on Û ± +± Û Windows XP anyway. Û ± +± Û Û ± +± Û It seems to run fine in Wine too, including under box86, just Û ± +± Û in case you need Pro Nouns on another little-endian OS. Û ± +± Û Û ± +± Û Û ± +± Û ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» Û ± +± ÛÄÄÄÄşºº INSTALL INFO ººşÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ ± +± Û ÈÍÍÍÍÍÍÍÍÍÍÍÍÍͼ Û ± +± Û Û ± +± Û Just open the EXE and enter the edition of Pro Nouns you want Û ± +± Û to use. Û ± +± Û Û ± +± Û Enjoy! Û ± +± Û Û ± +± Û ÉÍÍÍÍÍÍÍÍ» Û ± +± ÛÄÄÄÄÄÄÄşºº GREETS ººşÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ ± +± Û ÈÍÍÍÍÍÍÍͼ Û ± +± Û Û ± +± Û Greets fly out to HeLL LaBS members! Û ± +± Û Û ± +± Û Personal greets to: Û ± +± Û Û ± +± Û ¯ LiF and iliana, for their assistance in both testing and Û ± +± Û troubleshooting issues with the nightmare that is Win32 Û ± +± Û ¯ Luna, for making the original that inspired me to Û ± +± Û relearn the old Win32 API Û ± +± Û ¯ libXMP devs, for making a tracker library that works so Û ± +± Û well on any platform I've thrown it at with few issues Û ± +± Û Û ± +± Û ÉÍÍÍÍÍÍÍÍÍÍÍÍ» Û ± +± ÛÄÄÄÄÄşºº GROUP INFO ººşÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ ± +± Û ÈÍÍÍÍÍÍÍÍÍÍÍͼ Û ± +± Û Û ± +± Û irc...........: unlisted ;) Û ± +± Û email.........: unlisted ;) Û ± +± Û world wide web: http://cohost.org/hell-labs Û ± +± Û Û ± +± Û ÉÍÍÍÍÍÍÍÍ» Û ± +± ÛÄÄÄÄÄÄÄşºº LEGAL? ººşÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÛ ± +± Û ÈÍÍÍÍÍÍÍͼ Û ± +± Û Û ± +± Û The source code for this software is provided at the below Û ± +± Û link, under the BBHLv1: Û ± +± Û Û ± +± Û http://git.2ki.xyz/hell-labs/keygendr32 Û ± +± Û Û ± +± Û This software also uses libxmp, under the MIT license: Û ± +± Û Û ± +± Û Extended Module Player Û ± +± Û Copyright (C) 1996-2023 Claudio Matsuoka and Û ± +± Û Hipolito Carraro Jr Û ± +± Û Û ± +± Û Permission is hereby granted, free of charge, to any person Û ± +± Û obtaining a copy of this software and associated Û ± +± Û documentation files (the "Software"), to deal in the Û ± +± Û Software without restriction, including without limitation Û ± +± Û the rights to use, copy, modify, merge, publish, Û ± +± Û distribute, sublicense, and/or sell copies of the Software, Û ± +± Û and to permit persons to whom the Software is furnished to Û ± +± Û do so, subject to the following conditions: Û ± +± Û Û ± +± Û The above copyright notice and this permission notice shall Û ± +± Û be included in all copies or substantial portions of the Û ± +± Û Software. Û ± +± Û Û ± +± Û THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY Û ± +± Û KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE Û ± +± Û WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR Û ± +± Û PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS Û ± +± Û OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR Û ± +± Û OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR Û ± +± Û OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE Û ± +± Û SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Û ± +± Û Û ± +± ş ş ± +± ! ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸ ! ± +±ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´³ CALL ENDED... ³ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄı + ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍ; + diff --git a/keygendr.for.win32.HL.utf8.NFO b/keygendr.for.win32.HL.utf8.NFO new file mode 100644 index 0000000..d45801b --- /dev/null +++ b/keygendr.for.win32.HL.utf8.NFO @@ -0,0 +1,148 @@ + + â–„â–„â–„â–„â–„â–„â–„â–„â–„â–„â–„â–„â–„â–„â–„ + ▄▄▄█████████████████████▄▄▄ + ▄▄███████████████████████████████▄▄ + ▄████████████▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀████████████▄ + ▄█████████▀▀ ▀▀█████████▄ + ▄████████▀ â–„ â–„ ▀████████▄ + ████████▀ ▄█████▄ ▄█████▄ ▀████████ + ███████▀ ▄██████████▄ ▄██████████▄ ▀███████ + ███████▀ █████████████▄▄ ▄▄█████████████ ███████ + ▄██████ ██████▀████████▄████████▀██████ ██████▄ + ██████ ▀█████▄ ▀█████████████▀ ▄█████▀ ██████ + ██████ ██████ ▄███████████▄ ██████ ██████ + ▄█████▀ ▀███████████████████████████▀ ▀█████▄ + ██████ ████████████▀▀▀████████████ ██████ + ██████ ▄█████████▀ ▀█████████▄ ██████ + ██████ ▄██████████▀ ▀██████████▄ ██████ + ██████ ▄▄█████████████ █████████████▄▄ ██████ + ██████ ▄█████████▀ ██████ ██████ ▀█████████▄ ██████ + ██████ ███████▀ ██████ ██████ *hl*▀███████ ██████ + ██████ ███████████████████████████████████████████ ██████ + ██████ █████████████████████████████████████████ ██████ + ▀█████▄ ▀▀▀▀▀▀▀▀▀▀▀▀██████ ██████▀▀▀▀▀▀▀▀▀▀▀▀ ▄█████▀ + ██████▄ ██████ ██████ ▄██████ + ██████▄ ██████ ██████ ▄██████ + ▀███████ ▀█████▄█████▀ ▄██████▀ + ▀███████▄ ███████████ ▄███████▀ + ▀███████▄ ▀█████████▀ ▄████████ + ▀███████▄▄ ▀███████▀ ▄▄████████▀ + ▀█████████▄▄▄ ▄▄▄██████████▀ + ▀███████████████████████████████████▀▀ + ▀▀███████████████████████████▀▀ + ▀▀▀███████████████▀▀▀ + + + â–█▌ â–█▌ â–█▌â–█▌ ██ ██ + â–█▌ â–█▌ â–„â–„â–„â–„ â–█▌â–█▌ ██ â–„â–„â–„â–„â–„ ██ â–„â–„â–„ â–„â–„â–„â–„â–„ + â–███████▌▄██▀▀██▄â–█▌â–█▌ ██ ██▀▀▀█▌ ███▀▀██▄ ██▀▀▀██ + â–█▌ â–█▌██▄▄▄▄██â–█▌â–█▌ ██ ▄▄███▌ ██ ██ ▀███▄▄ + â–█▌ â–█▌██▄ â–„â–„â–█▌â–█▌ ██ ██▀ ▄█▌ ██▄ ▄██ â–„â–„ ▀▀██ + â–█▌ â–█▌ ▀████▀ â–█▌â–█▌ █████▌▀███▀██▌██▀███▀ ▀█████▀ + + +·█████████████████████████████████████████████████████████████████████· +·█████████████████████████████████████████████████████████████████████· +· · +:â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’â–’: +¡▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒¡ +│ │ +├─┬─────────────────────────────────────────────────────────────────┬─┤ +â–’ â–ˆ PRO NOUNS KEYGENDERATOR FOR WINDOWS â–ˆ â–’ +â–’ █────────────────────────────────╥────────────────────────────────█ â–’ +â–’ â–ˆ developer...: [ flurry ] â–ˆ name.....: [ keygendr.exe ] â–ˆ â–’ +â–’ â–ˆ tester......: [ LiFFY ] â–ˆ OS.......: [ WinAll ] â–ˆ â–’ +â–’ â–ˆ release date: [ 17 mar 2024 ] â–ˆ disks....: [ 01 x 1.44 ] â–ˆ â–’ +â–’ â–ˆ â–ˆ â–ˆ â–’ +â–’ â–ˆ â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•— â–ˆ â–ˆ â–’ +â–’ █───■║║ RELEASE INFO ║║■─────────╨────────────────────────────────█ â–’ +â–’ â–ˆ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â• â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ This is a port of the JavaScript version, by Luna. Check out â–ˆ â–’ +â–’ â–ˆ her version here: â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ http://tiredand.gay/keygender/ â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ This program should be compatible with Windows 2000 and up. â–ˆ â–’ +â–’ â–ˆ You might be able to run this on Windows 9x, but beware: when â–ˆ â–’ +â–’ â–ˆ we tested it, the system struggled to keep up! It's best on â–ˆ â–’ +â–’ â–ˆ Windows XP anyway. â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ It seems to run fine in Wine too, including under box86, just â–ˆ â–’ +â–’ â–ˆ in case you need Pro Nouns on another little-endian OS. â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ â•”â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•— â–ˆ â–’ +â–’ █────■║║ INSTALL INFO ║║■─────────────────────────────────────────█ â–’ +â–’ â–ˆ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â• â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ Just open the EXE and enter the edition of Pro Nouns you want â–ˆ â–’ +â–’ â–ˆ to use. â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ Enjoy! â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ â•”â•â•â•â•â•â•â•â•â•— â–ˆ â–’ +â–’ █───────■║║ GREETS ║║■────────────────────────────────────────────█ â–’ +â–’ â–ˆ â•šâ•â•â•â•â•â•â•â•â• â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ Greets fly out to HeLL LaBS members! â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ Personal greets to: â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ » LiF and iliana, for their assistance in both testing and â–ˆ â–’ +â–’ â–ˆ troubleshooting issues with the nightmare that is Win32 â–ˆ â–’ +â–’ â–ˆ » Luna, for making the original that inspired me to â–ˆ â–’ +â–’ â–ˆ relearn the old Win32 API â–ˆ â–’ +â–’ â–ˆ » libXMP devs, for making a tracker library that works so â–ˆ â–’ +â–’ â–ˆ well on any platform I've thrown it at with few issues â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ â•”â•â•â•â•â•â•â•â•â•â•â•â•â•— â–ˆ â–’ +â–’ █─────■║║ GROUP INFO ║║■──────────────────────────────────────────█ â–’ +â–’ â–ˆ â•šâ•â•â•â•â•â•â•â•â•â•â•â•â• â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ irc...........: unlisted ;) â–ˆ â–’ +â–’ â–ˆ email.........: unlisted ;) â–ˆ â–’ +â–’ â–ˆ world wide web: http://cohost.org/hell-labs â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ â•”â•â•â•â•â•â•â•â•â•— â–ˆ â–’ +â–’ █───────■║║ LEGAL? ║║■────────────────────────────────────────────█ â–’ +â–’ â–ˆ â•šâ•â•â•â•â•â•â•â•â• â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ The source code for this software is provided at the below â–ˆ â–’ +â–’ â–ˆ link, under the BBHLv1: â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ http://git.2ki.xyz/hell-labs/keygendr32 â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ This software also uses libxmp, under the MIT license: â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ Extended Module Player â–ˆ â–’ +â–’ â–ˆ Copyright (C) 1996-2023 Claudio Matsuoka and â–ˆ â–’ +â–’ â–ˆ Hipolito Carraro Jr â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ Permission is hereby granted, free of charge, to any person â–ˆ â–’ +â–’ â–ˆ obtaining a copy of this software and associated â–ˆ â–’ +â–’ â–ˆ documentation files (the "Software"), to deal in the â–ˆ â–’ +â–’ â–ˆ Software without restriction, including without limitation â–ˆ â–’ +â–’ â–ˆ the rights to use, copy, modify, merge, publish, â–ˆ â–’ +â–’ â–ˆ distribute, sublicense, and/or sell copies of the Software, â–ˆ â–’ +â–’ â–ˆ and to permit persons to whom the Software is furnished to â–ˆ â–’ +â–’ â–ˆ do so, subject to the following conditions: â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ The above copyright notice and this permission notice shall â–ˆ â–’ +â–’ â–ˆ be included in all copies or substantial portions of the â–ˆ â–’ +â–’ â–ˆ Software. â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–ˆ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY â–ˆ â–’ +â–’ â–ˆ KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE â–ˆ â–’ +â–’ â–ˆ WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR â–ˆ â–’ +â–’ â–ˆ PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS â–ˆ â–’ +â–’ â–ˆ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR â–ˆ â–’ +â–’ â–ˆ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR â–ˆ â–’ +â–’ â–ˆ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE â–ˆ â–’ +â–’ â–ˆ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. â–ˆ â–’ +â–’ â–ˆ â–ˆ â–’ +â–’ â–  â–  â–’ +â–’ ! â•’â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•• ! â–’ +▒─────────────────────────┤│ CALL ENDED... │├─────────────────────────▒ + ╘â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•› +