Add user-friendliness
This commit is contained in:
@@ -15,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Render", "source\plugins\Re
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fakedll", "source\fakedll\fakedll.vcxproj", "{B49C6ABE-931C-4F91-9A94-21A41A305FEE}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DivaSound", "source\plugins\DivaSound\DivaSound.vcxproj", "{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
@@ -71,6 +73,12 @@ Global
|
||||
{B49C6ABE-931C-4F91-9A94-21A41A305FEE}.Release|x64.Build.0 = Release|x64
|
||||
{B49C6ABE-931C-4F91-9A94-21A41A305FEE}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B49C6ABE-931C-4F91-9A94-21A41A305FEE}.Release|x86.Build.0 = Release|Win32
|
||||
{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}.Debug|x64.Build.0 = Debug|x64
|
||||
{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}.Debug|x86.ActiveCfg = Debug|x64
|
||||
{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}.Release|x64.ActiveCfg = Release|x64
|
||||
{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}.Release|x64.Build.0 = Release|x64
|
||||
{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}.Release|x86.ActiveCfg = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
[General]
|
||||
# You can choose 2 channel or 4 channel mode.
|
||||
# 4 channels uses front channels for speakers and rear channels as headphones.
|
||||
# 2 channels only has headphones output (with in-game volume bypassed).
|
||||
Channels=2
|
||||
|
||||
# 16 or 24 bit integer and 32 bit float output are supported.
|
||||
# If you don't know what this means, you should leave it at 16.
|
||||
# On some versions of Windows floating point samples may increase latency.
|
||||
Bit_Depth=16
|
||||
|
||||
# This can be WASAPI, DirectSound, WASAPI_Exclusive, or ASIO.
|
||||
# Only use DirectSound if WASAPI doesn't work for some reason.
|
||||
# WASAPI_Exclusive may not work with some hardware, but can have lower latency.
|
||||
# ASIO requires special driver support.
|
||||
# ASIO doesn't use the buffer settings. Use ASIO config instead.
|
||||
# For full descriptions of the backends see https://github.com/somewhatlurker/DivaSound/wiki/Backends.
|
||||
Backend=WASAPI
|
||||
|
||||
# If the game crashes when loading, try setting this to 0.
|
||||
Alternate_Init=1
|
||||
|
||||
[Buffer]
|
||||
# Sets the requested buffer size in milliseconds.
|
||||
# Try increasing this if audio stutters or desyncs.
|
||||
# WASAPI will usually provide a larger buffer than specified.
|
||||
# You can check the actual buffer size by enabling debug_component.
|
||||
Buffer_Size=10
|
||||
|
||||
# Sets how many periods to use.
|
||||
# Fewer periods = lower latency, but it may cause issues.
|
||||
# You probably shouldn't set this below 2, and increasing it probably isn't necessary.
|
||||
Periods=2
|
||||
|
||||
[ASIO]
|
||||
# Sets the device ID.
|
||||
# 0=first device(...), -1=first available device
|
||||
Device=-1
|
||||
|
||||
# When set to 1 the ASIO driver config will open alongside the game.
|
||||
# Use this to adjust output settings, then disable it.
|
||||
Show_Config=0
|
||||
Binary file not shown.
@@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{EE1A551A-49A0-40F2-8C2E-862D0AE55B43}</ProjectGuid>
|
||||
<RootNamespace>DivaSound</RootNamespace>
|
||||
<ProjectName>DivaSound</ProjectName>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);detours/include;miniaudio;bassasio</IncludePath>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;detours/lib;bassasio</LibraryPath>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);detours/include;miniaudio;bassasio</IncludePath>
|
||||
<LibraryPath>$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(NETFXKitsDir)Lib\um\x64;detours/lib;bassasio</LibraryPath>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>detours.lib;syelog.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>detours.lib;syelog.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\framework.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
BASSASIO 1.4 C/C++ header file
|
||||
Copyright (c) 2005-2019 Un4seen Developments Ltd.
|
||||
|
||||
See the BASSASIO.CHM file for more detailed documentation
|
||||
*/
|
||||
/*
|
||||
DivaSound version -- loads the required functions at runtime
|
||||
*/
|
||||
|
||||
#ifndef BASSASIO_H
|
||||
#define BASSASIO_H
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BASSASIODEF
|
||||
#define BASSASIODEF(f) WINAPI f
|
||||
#endif
|
||||
|
||||
#define BASSASIOVERSION 0x104 // API version
|
||||
|
||||
// error codes returned by BASS_ASIO_ErrorGetCode
|
||||
#define BASS_OK 0 // all is OK
|
||||
#define BASS_ERROR_FILEOPEN 2 // can't open the file
|
||||
#define BASS_ERROR_DRIVER 3 // can't find a free/valid driver
|
||||
#define BASS_ERROR_HANDLE 5 // invalid handle
|
||||
#define BASS_ERROR_FORMAT 6 // unsupported sample format
|
||||
#define BASS_ERROR_INIT 8 // BASS_ASIO_Init has not been successfully called
|
||||
#define BASS_ERROR_START 9 // BASS_ASIO_Start has/hasn't been called
|
||||
#define BASS_ERROR_ALREADY 14 // already initialized/started
|
||||
#define BASS_ERROR_NOCHAN 18 // no channels are enabled
|
||||
#define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified
|
||||
#define BASS_ERROR_DEVICE 23 // illegal device number
|
||||
#define BASS_ERROR_NOTAVAIL 37 // not available
|
||||
#define BASS_ERROR_UNKNOWN -1 // some other mystery error
|
||||
|
||||
// BASS_ASIO_Init flags
|
||||
#define BASS_ASIO_THREAD 1 // host driver in dedicated thread
|
||||
#define BASS_ASIO_JOINORDER 2 // order joined channels by when they were joined
|
||||
|
||||
// device info structure
|
||||
typedef struct {
|
||||
const char *name; // description
|
||||
const char *driver; // driver
|
||||
} BASS_ASIO_DEVICEINFO;
|
||||
|
||||
typedef struct {
|
||||
char name[32]; // driver name
|
||||
DWORD version; // driver version
|
||||
DWORD inputs; // number of inputs
|
||||
DWORD outputs; // number of outputs
|
||||
DWORD bufmin; // minimum buffer length
|
||||
DWORD bufmax; // maximum buffer length
|
||||
DWORD bufpref; // preferred/default buffer length
|
||||
int bufgran; // buffer length granularity
|
||||
DWORD initflags; // BASS_ASIO_Init "flags" parameter
|
||||
} BASS_ASIO_INFO;
|
||||
|
||||
typedef struct {
|
||||
DWORD group;
|
||||
DWORD format; // sample format (BASS_ASIO_FORMAT_xxx)
|
||||
char name[32]; // channel name
|
||||
} BASS_ASIO_CHANNELINFO;
|
||||
|
||||
// sample formats
|
||||
#define BASS_ASIO_FORMAT_16BIT 16 // 16-bit integer
|
||||
#define BASS_ASIO_FORMAT_24BIT 17 // 24-bit integer
|
||||
#define BASS_ASIO_FORMAT_32BIT 18 // 32-bit integer
|
||||
#define BASS_ASIO_FORMAT_FLOAT 19 // 32-bit floating-point
|
||||
#define BASS_ASIO_FORMAT_DSD_LSB 32 // DSD (LSB 1st)
|
||||
#define BASS_ASIO_FORMAT_DSD_MSB 33 // DSD (MSB 1st)
|
||||
#define BASS_ASIO_FORMAT_DITHER 0x100 // flag: apply dither when converting from floating-point to integer
|
||||
|
||||
// BASS_ASIO_ChannelReset flags
|
||||
#define BASS_ASIO_RESET_ENABLE 1 // disable channel
|
||||
#define BASS_ASIO_RESET_JOIN 2 // unjoin channel
|
||||
#define BASS_ASIO_RESET_PAUSE 4 // unpause channel
|
||||
#define BASS_ASIO_RESET_FORMAT 8 // reset sample format to native format
|
||||
#define BASS_ASIO_RESET_RATE 16 // reset sample rate to device rate
|
||||
#define BASS_ASIO_RESET_VOLUME 32 // reset volume to 1.0
|
||||
#define BASS_ASIO_RESET_JOINED 0x10000 // apply to joined channels too
|
||||
|
||||
// BASS_ASIO_ChannelIsActive return values
|
||||
#define BASS_ASIO_ACTIVE_DISABLED 0
|
||||
#define BASS_ASIO_ACTIVE_ENABLED 1
|
||||
#define BASS_ASIO_ACTIVE_PAUSED 2
|
||||
|
||||
typedef DWORD (CALLBACK ASIOPROC)(BOOL input, DWORD channel, void *buffer, DWORD length, void *user);
|
||||
/* ASIO channel callback function.
|
||||
input : Input? else output
|
||||
channel: Channel number
|
||||
buffer : Buffer containing the sample data
|
||||
length : Number of bytes
|
||||
user : The 'user' parameter given when calling BASS_ASIO_ChannelEnable
|
||||
RETURN : The number of bytes written (ignored with input channels) */
|
||||
|
||||
typedef void (CALLBACK ASIONOTIFYPROC)(DWORD notify, void *user);
|
||||
/* Driver notification callback function.
|
||||
notify : The notification (BASS_ASIO_NOTIFY_xxx)
|
||||
user : The 'user' parameter given when calling BASS_ASIO_SetNotify */
|
||||
|
||||
// driver notifications
|
||||
#define BASS_ASIO_NOTIFY_RATE 1 // sample rate change
|
||||
#define BASS_ASIO_NOTIFY_RESET 2 // reset (reinitialization) request
|
||||
|
||||
// BASS_ASIO_ChannelGetLevel flags
|
||||
#define BASS_ASIO_LEVEL_RMS 0x1000000
|
||||
|
||||
HMODULE bassAsioModule = LoadLibraryW(L"bassasio.dll");
|
||||
|
||||
DWORD(WINAPI* BASS_ASIO_GetVersion)() = (DWORD(WINAPI*)())GetProcAddress(bassAsioModule, "BASS_ASIO_GetVersion");
|
||||
// BOOL BASSASIODEF(BASS_ASIO_SetUnicode)(BOOL unicode);
|
||||
// DWORD BASSASIODEF(BASS_ASIO_ErrorGetCode)();
|
||||
// BOOL BASSASIODEF(BASS_ASIO_GetDeviceInfo)(DWORD device, BASS_ASIO_DEVICEINFO *info);
|
||||
// DWORD BASSASIODEF(BASS_ASIO_AddDevice)(const GUID *clsid, const char *driver, const char *name);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_SetDevice)(DWORD device);
|
||||
// DWORD BASSASIODEF(BASS_ASIO_GetDevice)();
|
||||
BOOL(WINAPI* BASS_ASIO_Init)(int device, DWORD flags) = (BOOL(WINAPI*)(int device, DWORD flags))GetProcAddress(bassAsioModule, "BASS_ASIO_Init");
|
||||
BOOL(WINAPI* BASS_ASIO_Free)() = (BOOL(WINAPI*)())GetProcAddress(bassAsioModule, "BASS_ASIO_Free");
|
||||
// BOOL BASSASIODEF(BASS_ASIO_Lock)(BOOL lock);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_SetNotify)(ASIONOTIFYPROC *proc, void *user);
|
||||
BOOL(WINAPI* BASS_ASIO_ControlPanel)() = (BOOL(WINAPI*)())GetProcAddress(bassAsioModule, "BASS_ASIO_ControlPanel");
|
||||
BOOL(WINAPI* BASS_ASIO_GetInfo)(BASS_ASIO_INFO *info) = (BOOL(WINAPI*)(BASS_ASIO_INFO *info))GetProcAddress(bassAsioModule, "BASS_ASIO_GetInfo");
|
||||
BOOL(WINAPI* BASS_ASIO_CheckRate)(double rate) = (BOOL(WINAPI*)(double rate))GetProcAddress(bassAsioModule, "BASS_ASIO_CheckRate");
|
||||
BOOL(WINAPI* BASS_ASIO_SetRate)(double rate) = (BOOL(WINAPI*)(double rate))GetProcAddress(bassAsioModule, "BASS_ASIO_SetRate");
|
||||
double(WINAPI* BASS_ASIO_GetRate)() = (double(WINAPI*)())GetProcAddress(bassAsioModule, "BASS_ASIO_GetRate");
|
||||
BOOL(WINAPI* BASS_ASIO_Start)(DWORD buflen, DWORD threads) = (BOOL(WINAPI*)(DWORD buflen, DWORD threads))GetProcAddress(bassAsioModule, "BASS_ASIO_Start");
|
||||
BOOL(WINAPI* BASS_ASIO_Stop)() = (BOOL(WINAPI*)())GetProcAddress(bassAsioModule, "BASS_ASIO_Stop");
|
||||
BOOL(WINAPI* BASS_ASIO_IsStarted)() = (BOOL(WINAPI*)())GetProcAddress(bassAsioModule, "BASS_ASIO_IsStarted");
|
||||
// DWORD BASSASIODEF(BASS_ASIO_GetLatency)(BOOL input);
|
||||
// float BASSASIODEF(BASS_ASIO_GetCPU)();
|
||||
// BOOL BASSASIODEF(BASS_ASIO_Monitor)(int input, DWORD output, DWORD gain, DWORD state, DWORD pan);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_SetDSD)(BOOL dsd);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_Future)(DWORD selector, void *param);
|
||||
|
||||
// BOOL BASSASIODEF(BASS_ASIO_ChannelGetInfo)(BOOL input, DWORD channel, BASS_ASIO_CHANNELINFO *info);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_ChannelReset)(BOOL input, int channel, DWORD flags);
|
||||
BOOL(WINAPI* BASS_ASIO_ChannelEnable)(BOOL input, DWORD channel, ASIOPROC *proc, void *user) = (BOOL(WINAPI*)(BOOL input, DWORD channel, ASIOPROC *proc, void *user))GetProcAddress(bassAsioModule, "BASS_ASIO_ChannelEnable");
|
||||
// BOOL BASSASIODEF(BASS_ASIO_ChannelEnableMirror)(DWORD channel, BOOL input2, DWORD channel2);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_ChannelEnableBASS)(BOOL input, DWORD channel, DWORD handle, BOOL join);
|
||||
BOOL(WINAPI* BASS_ASIO_ChannelJoin)(BOOL input, DWORD channel, int channel2) = (BOOL(WINAPI*)(BOOL input, DWORD channel, int channel2))GetProcAddress(bassAsioModule, "BASS_ASIO_ChannelJoin");
|
||||
// BOOL BASSASIODEF(BASS_ASIO_ChannelPause)(BOOL input, DWORD channel);
|
||||
// DWORD BASSASIODEF(BASS_ASIO_ChannelIsActive)(BOOL input, DWORD channel);
|
||||
BOOL(WINAPI* BASS_ASIO_ChannelSetFormat)(BOOL input, DWORD channel, DWORD format) = (BOOL(WINAPI*)(BOOL input, DWORD channel, DWORD format))GetProcAddress(bassAsioModule, "BASS_ASIO_ChannelSetFormat");
|
||||
// DWORD BASSASIODEF(BASS_ASIO_ChannelGetFormat)(BOOL input, DWORD channel);
|
||||
BOOL(WINAPI* BASS_ASIO_ChannelSetRate)(BOOL input, DWORD channel, double rate) = (BOOL(WINAPI*)(BOOL input, DWORD channel, double rate))GetProcAddress(bassAsioModule, "BASS_ASIO_ChannelSetRate");
|
||||
// double BASSASIODEF(BASS_ASIO_ChannelGetRate)(BOOL input, DWORD channel);
|
||||
// BOOL BASSASIODEF(BASS_ASIO_ChannelSetVolume)(BOOL input, int channel, float volume);
|
||||
// float BASSASIODEF(BASS_ASIO_ChannelGetVolume)(BOOL input, int channel);
|
||||
// float BASSASIODEF(BASS_ASIO_ChannelGetLevel)(BOOL input, DWORD channel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Common version parameters.
|
||||
//
|
||||
// Microsoft Research Detours Package, Version 4.0.1
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#define _USING_V110_SDK71_ 1
|
||||
#include "winver.h"
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
#else
|
||||
#ifndef DETOURS_STRINGIFY
|
||||
#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
|
||||
#define DETOURS_STRINGIFY_(x) #x
|
||||
#endif
|
||||
|
||||
#define VER_FILEFLAGSMASK 0x3fL
|
||||
#define VER_FILEFLAGS 0x0L
|
||||
#define VER_FILEOS 0x00040004L
|
||||
#define VER_FILETYPE 0x00000002L
|
||||
#define VER_FILESUBTYPE 0x00000000L
|
||||
#endif
|
||||
#define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS)
|
||||
@@ -0,0 +1,89 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (syelog.h of syelog.lib)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
#ifndef _SYELOGD_H_
|
||||
#define _SYELOGD_H_
|
||||
#include <stdarg.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog"
|
||||
#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog"
|
||||
#ifdef UNICODE
|
||||
#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW
|
||||
#else
|
||||
#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff)
|
||||
|
||||
typedef struct _SYELOG_MESSAGE
|
||||
{
|
||||
USHORT nBytes;
|
||||
BYTE nFacility;
|
||||
BYTE nSeverity;
|
||||
DWORD nProcessId;
|
||||
FILETIME ftOccurance;
|
||||
BOOL fTerminate;
|
||||
CHAR szMessage[SYELOG_MAXIMUM_MESSAGE];
|
||||
} SYELOG_MESSAGE, *PSYELOG_MESSAGE;
|
||||
|
||||
|
||||
// Facility Codes.
|
||||
//
|
||||
#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel
|
||||
#define SYELOG_FACILITY_SECURITY 0x20 // OS Security
|
||||
#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal
|
||||
#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon
|
||||
#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application
|
||||
#define SYELOG_FACILITY_USER 0x60 // User self-generated.
|
||||
#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined.
|
||||
|
||||
// Severity Codes.
|
||||
//
|
||||
#define SYELOG_SEVERITY_FATAL 0x00 // System is dead.
|
||||
#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately.
|
||||
#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition.
|
||||
#define SYELOG_SEVERITY_ERROR 0x30 // Error
|
||||
#define SYELOG_SEVERITY_WARNING 0x40 // Warning
|
||||
#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition.
|
||||
#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational
|
||||
#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed
|
||||
#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded
|
||||
#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging
|
||||
|
||||
// Logging Functions.
|
||||
//
|
||||
VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility);
|
||||
VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...);
|
||||
VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args);
|
||||
VOID SyelogClose(BOOL fTerminate);
|
||||
|
||||
#pragma warning(pop)
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // _SYELOGD_H_
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,412 @@
|
||||
#include "framework.h"
|
||||
#include <detours.h>
|
||||
#pragma comment(lib, "detours.lib")
|
||||
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <strsafe.h>
|
||||
#include <bassasio.h>
|
||||
|
||||
void InjectCode(void* address, const std::vector<uint8_t> data)
|
||||
{
|
||||
const size_t byteCount = data.size() * sizeof(uint8_t);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
memcpy(address, data.data(), byteCount);
|
||||
VirtualProtect(address, byteCount, oldProtect, nullptr);
|
||||
}
|
||||
|
||||
void NopBytes(void* address, unsigned int num)
|
||||
{
|
||||
std::vector<uint8_t> newbytes = {};
|
||||
|
||||
for (int i = 0; i < num; ++i) newbytes.push_back(0x90);
|
||||
|
||||
InjectCode(address, newbytes);
|
||||
}
|
||||
|
||||
void resizeInternalBuffers(uint64_t frames)
|
||||
{
|
||||
divaBufSizeInFrames = frames;
|
||||
divaAudioMixCls->mixbuffer = new float[divaBufSizeInFrames * 4];
|
||||
divaAudioMixCls->mixbuffer_size = divaBufSizeInFrames * 4 * 4;
|
||||
divaAudioMixCls->state2->buffer = new float[divaBufSizeInFrames * 4];
|
||||
divaAudioMixCls->state2->buffer_size = divaBufSizeInFrames * 4 * 4;
|
||||
divaAudCls->buffer_size = divaBufSizeInFrames;
|
||||
printf("[DivaSound] Resized internal buffers to %d frames\n", frames);
|
||||
}
|
||||
|
||||
void resizeTestLoop()
|
||||
{
|
||||
bool dir = true;
|
||||
while (true)
|
||||
{
|
||||
Sleep(5000);
|
||||
|
||||
if (dir)
|
||||
resizeInternalBuffers(divaBufSizeInFrames + 3000);
|
||||
else
|
||||
resizeInternalBuffers(divaBufSizeInFrames - 3000);
|
||||
|
||||
dir = !dir;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void audioCallback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
{
|
||||
(void)pDevice;
|
||||
(void)pOutput;
|
||||
(void)pInput;
|
||||
(void)frameCount;
|
||||
|
||||
//printf("%d", divaAudCls->idk);
|
||||
|
||||
if (frameCount > divaBufSizeInFrames)
|
||||
{
|
||||
printf("[DivaSound] Warning: PDAFT buffer is too small\n");
|
||||
//frameCount = divaBufSizeInFrames;
|
||||
|
||||
// allocate a larger buffer if necessary.
|
||||
// add 128 frames of padding because this isn't normal and we want to avoid it happening again if possible.
|
||||
resizeInternalBuffers(frameCount + 128);
|
||||
}
|
||||
|
||||
divaAudioFillbuffer(divaAudioMixCls, (int16_t*)pOutput, frameCount, 0, 0);
|
||||
//printf("%p %d\n", divaAudioMixCls, ((int16_t*)pOutput)[0]);
|
||||
|
||||
if (bitDepth > 16) // we should generate the output buffer ourselves
|
||||
{
|
||||
float volumes[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
volumes[i] = divaAudioMixCls->volume_master * divaAudioMixCls->volume_channels[i];
|
||||
}
|
||||
|
||||
|
||||
int startChannel = 4 - nChannels;
|
||||
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
for (int currentChannel = startChannel; currentChannel < 4; currentChannel++)
|
||||
{
|
||||
// note: currentChannel is for the game's buffer, outputChannel is for our output buffer.
|
||||
// outputChannel should also be used for volumes.
|
||||
int outputChannel = currentChannel - startChannel;
|
||||
|
||||
if (bitDepth == 24) // 24 bit int output
|
||||
{
|
||||
int32_t out_val = divaAudioMixCls->mixbuffer[i*4 + currentChannel] * volumes[outputChannel] * 8388607.0f;
|
||||
|
||||
if (out_val > 8388607) out_val = 8388607;
|
||||
else if (out_val < -8388608) out_val = -8388608;
|
||||
|
||||
uint64_t out_pos = (i*nChannels + outputChannel) * 3;
|
||||
|
||||
((byte*)pOutput)[out_pos] = out_val;
|
||||
((byte*)pOutput)[out_pos + 1] = out_val >> 8;
|
||||
((byte*)pOutput)[out_pos + 2] = out_val >> 16;
|
||||
}
|
||||
|
||||
else if (bitDepth == 32) // floating point output
|
||||
{
|
||||
((float*)pOutput)[i*nChannels + outputChannel] = divaAudioMixCls->mixbuffer[i*4 + currentChannel] * volumes[outputChannel];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DWORD asioCallback(bool input, DWORD channel, void* buffer, DWORD length, void* user)
|
||||
{
|
||||
ma_uint32 frames = length * 8 / bitDepth / nChannels;
|
||||
audioCallback(&device, buffer, NULL, frames);
|
||||
return length;
|
||||
}
|
||||
|
||||
void asioClose()
|
||||
{
|
||||
if (BASS_ASIO_IsStarted()) BASS_ASIO_Stop();
|
||||
BASS_ASIO_Free();
|
||||
}
|
||||
|
||||
void loadConfig()
|
||||
{
|
||||
nChannels = GetPrivateProfileIntW(L"general", L"channels", 2, CONFIG_FILE);
|
||||
if (nChannels != 4) nChannels = 2;
|
||||
|
||||
|
||||
bitDepth = GetPrivateProfileIntW(L"general", L"bit_depth", 16, CONFIG_FILE);
|
||||
if (bitDepth != 32 && bitDepth != 24) bitDepth = 16;
|
||||
|
||||
|
||||
requestBuffer = GetPrivateProfileIntW(L"buffer", L"buffer_size", 10, CONFIG_FILE);
|
||||
if (requestBuffer < 0) requestBuffer = 0;
|
||||
|
||||
|
||||
nPeriods = GetPrivateProfileIntW(L"buffer", L"periods", 2, CONFIG_FILE);
|
||||
if (nPeriods < 1) nPeriods = 1;
|
||||
|
||||
|
||||
useOldInit = GetPrivateProfileIntW(L"general", L"alternate_init", 1, CONFIG_FILE) > 0 ? false : true;
|
||||
|
||||
|
||||
GetPrivateProfileStringW(L"general", L"backend", L"wasapi", backendName, 32, CONFIG_FILE);
|
||||
for (wchar_t& chr : backendName)
|
||||
chr = towlower(chr);
|
||||
|
||||
useAsio = false;
|
||||
maSharemode = ma_share_mode_shared;
|
||||
|
||||
if (lstrcmpW(backendName, L"asio") == 0)
|
||||
{
|
||||
StringCchCopyW(backendName, 32, L"ASIO");
|
||||
useAsio = true;
|
||||
}
|
||||
else if (lstrcmpW(backendName, L"directsound") == 0)
|
||||
{
|
||||
StringCchCopyW(backendName, 32, L"DirectSound");
|
||||
maBackend = ma_backend_dsound;
|
||||
}
|
||||
else if (lstrcmpW(backendName, L"wasapi_exclusive") == 0)
|
||||
{
|
||||
StringCchCopyW(backendName, 32, L"WASAPI (Exclusive mode)");
|
||||
maBackend = ma_backend_wasapi;
|
||||
maSharemode = ma_share_mode_exclusive;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringCchCopyW(backendName, 32, L"WASAPI");
|
||||
maBackend = ma_backend_wasapi;
|
||||
}
|
||||
|
||||
|
||||
asioDevice = GetPrivateProfileIntW(L"asio", L"device", -1, CONFIG_FILE);
|
||||
|
||||
showAsioPanel = GetPrivateProfileIntW(L"asio", L"show_config", 0, CONFIG_FILE) > 0 ? true : false;
|
||||
}
|
||||
|
||||
void hookedAudioInit(initClass *cls, uint64_t unk, uint64_t unk2)
|
||||
{
|
||||
//printf("[DivaSound] Loaded\n");
|
||||
printf("[DivaSound] Output config: %S %dch %dbit\n", backendName, nChannels, bitDepth);
|
||||
|
||||
divaAudCls = cls;
|
||||
|
||||
if (useOldInit)
|
||||
{
|
||||
printf("[DivaSound] Using old initialisation method\n");
|
||||
// let the game set some stuff up
|
||||
// might be necessary sometimes
|
||||
divaAudioInit(divaAudCls, unk, unk2);
|
||||
//printf("[DivaSound] Game audio initialised\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// setup some variables instead of using the original init function
|
||||
divaAudCls->mixer = new audioMixer();
|
||||
divaAudCls->mixer->volume_master = 1.0f;
|
||||
divaAudCls->mixer->volume_channels[0] = 1.0f;
|
||||
divaAudCls->mixer->volume_channels[1] = 1.0f;
|
||||
divaAudCls->mixer->volume_channels[2] = 1.0f;
|
||||
divaAudCls->mixer->volume_channels[3] = 1.0f;
|
||||
divaAudCls->mixer->audioClass = divaAudCls;
|
||||
|
||||
mtx_init(&divaAudCls->mixer->volume_mutex, 2);
|
||||
}
|
||||
|
||||
divaAudioMixCls = divaAudCls->mixer;
|
||||
|
||||
divaAudCls->channels = nChannels; // this could replace stereo patch
|
||||
divaAudCls->rate = 44100; // really does nothing
|
||||
divaAudCls->depth = bitDepth; // setting this to something other than 16 just removes output
|
||||
|
||||
|
||||
if (useAsio)
|
||||
{
|
||||
if (BASS_ASIO_Init == NULL)
|
||||
{
|
||||
printf("[DivaSound] BASS ASIO not loaded...\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (HIWORD(BASS_ASIO_GetVersion()) != BASSASIOVERSION)
|
||||
{
|
||||
printf("[DivaSound] Incorrect BASS ASIO version. Use 1.4.0.0.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!BASS_ASIO_Init(asioDevice, BASS_ASIO_THREAD))
|
||||
{
|
||||
printf("[DivaSound] Failed to initialize device\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(showAsioPanel) BASS_ASIO_ControlPanel();
|
||||
|
||||
if (!BASS_ASIO_ChannelEnable(false, 0, (ASIOPROC*)asioCallback, NULL))
|
||||
{
|
||||
printf("[DivaSound] Failed to enable channels\n");
|
||||
BASS_ASIO_Free();
|
||||
return;
|
||||
}
|
||||
for (int i = 1; i < nChannels; i++)
|
||||
{
|
||||
if (!BASS_ASIO_ChannelJoin(false, i, 0))
|
||||
{
|
||||
printf("[DivaSound] Failed to enable channels\n");
|
||||
BASS_ASIO_Free();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (BASS_ASIO_CheckRate(44100))
|
||||
BASS_ASIO_SetRate(44100);
|
||||
|
||||
BASS_ASIO_ChannelSetRate(false, 0, 44100);
|
||||
|
||||
if (bitDepth == 32)
|
||||
BASS_ASIO_ChannelSetFormat(false, 0, BASS_ASIO_FORMAT_FLOAT);
|
||||
else if (bitDepth == 24)
|
||||
BASS_ASIO_ChannelSetFormat(false, 0, BASS_ASIO_FORMAT_24BIT);
|
||||
else
|
||||
BASS_ASIO_ChannelSetFormat(false, 0, BASS_ASIO_FORMAT_16BIT);
|
||||
|
||||
|
||||
BASS_ASIO_INFO asioInfo;
|
||||
BASS_ASIO_GetInfo(&asioInfo);
|
||||
double actualRate = BASS_ASIO_GetRate();
|
||||
|
||||
printf("[DivaSound] Output buffer size: %d (%dms at %dHz)\n", asioInfo.bufpref, (int)(asioInfo.bufpref * 1000 / actualRate), (int)actualRate);
|
||||
|
||||
divaBufSizeInFrames = asioInfo.bufpref * 44100 / actualRate;
|
||||
divaBufSizeInMilliseconds = divaBufSizeInFrames * 1000 / 44100;
|
||||
printf("[DivaSound] PDAFT buffer size: %d (%dms at %dHz)\n", divaBufSizeInFrames, divaBufSizeInMilliseconds, 44100);
|
||||
|
||||
|
||||
divaAudioAllocMixer(divaAudioMixCls, unk, unk2, divaBufSizeInFrames);
|
||||
printf("[DivaSound] Created internal audio mixer\n");
|
||||
|
||||
if (!BASS_ASIO_Start(asioInfo.bufpref, 1))
|
||||
{
|
||||
printf("[DivaSound] Failed to start playback device\n");
|
||||
BASS_ASIO_Free();
|
||||
return;
|
||||
}
|
||||
printf("[DivaSound] Started playback\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ma_backend backends[] = { maBackend };
|
||||
|
||||
contextConfig = ma_context_config_init();
|
||||
contextConfig.threadPriority = ma_thread_priority_highest;
|
||||
|
||||
if (ma_context_init(backends, sizeof(backends) / sizeof(backends[0]), &contextConfig, &context) != MA_SUCCESS) {
|
||||
printf("[DivaSound] Failed to initialize context\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
deviceConfig = ma_device_config_init(ma_device_type_playback);
|
||||
deviceConfig.playback.channels = nChannels;
|
||||
deviceConfig.sampleRate = 44100;
|
||||
deviceConfig.bufferSizeInMilliseconds = requestBuffer; // actual result may be larger
|
||||
deviceConfig.periods = nPeriods;
|
||||
deviceConfig.dataCallback = audioCallback;
|
||||
deviceConfig.pUserData = NULL;
|
||||
deviceConfig.playback.shareMode = maSharemode;
|
||||
|
||||
if (bitDepth == 32)
|
||||
deviceConfig.playback.format = ma_format_f32;
|
||||
else if (bitDepth == 24)
|
||||
deviceConfig.playback.format = ma_format_s24;
|
||||
else
|
||||
deviceConfig.playback.format = ma_format_s16;
|
||||
|
||||
if (nChannels == 4)
|
||||
{
|
||||
deviceConfig.playback.channelMap[0] = MA_CHANNEL_FRONT_LEFT;
|
||||
deviceConfig.playback.channelMap[1] = MA_CHANNEL_FRONT_RIGHT;
|
||||
deviceConfig.playback.channelMap[2] = MA_CHANNEL_BACK_LEFT;
|
||||
deviceConfig.playback.channelMap[3] = MA_CHANNEL_BACK_RIGHT;
|
||||
}
|
||||
|
||||
|
||||
if (ma_device_init(&context, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("[DivaSound] Failed to open playback device\n");
|
||||
ma_context_uninit(&context);
|
||||
return;
|
||||
}
|
||||
//printf("[DivaSound] Opened playback device\n");
|
||||
|
||||
|
||||
maInternalBufferSizeInMilliseconds = device.playback.internalBufferSizeInFrames * 1000 / device.playback.internalSampleRate; // because miniaudio doesn't seem to have this
|
||||
printf("[DivaSound] Output buffer size: %d (%dms at %dHz)\n", device.playback.internalBufferSizeInFrames, maInternalBufferSizeInMilliseconds, device.playback.internalSampleRate);
|
||||
printf("[DivaSound] Buffer periods: %d\n", device.playback.internalPeriods);
|
||||
|
||||
divaBufSizeInFrames = device.playback.internalBufferSizeInFrames * device.sampleRate / device.playback.internalSampleRate; // +128; // 128 is just a bit extra in case resampling needs it or something. idk
|
||||
divaBufSizeInMilliseconds = divaBufSizeInFrames * 1000 / device.sampleRate;
|
||||
printf("[DivaSound] PDAFT buffer size: %d (%dms at %dHz)\n", divaBufSizeInFrames, divaBufSizeInMilliseconds, device.sampleRate);
|
||||
|
||||
|
||||
divaAudioAllocMixer(divaAudioMixCls, unk, unk2, divaBufSizeInFrames);
|
||||
printf("[DivaSound] Created internal audio mixer\n");
|
||||
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("[DivaSound] Failed to start playback device\n");
|
||||
ma_device_uninit(&device);
|
||||
ma_context_uninit(&context);
|
||||
return;
|
||||
}
|
||||
printf("[DivaSound] Started playback\n");
|
||||
}
|
||||
|
||||
divaAudCls->buffer_size = divaBufSizeInFrames;
|
||||
//loopThread = std::thread(resizeTestLoop);
|
||||
}
|
||||
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
loadConfig();
|
||||
|
||||
if (useOldInit)
|
||||
{
|
||||
// these patches are only needed if calling the game's own init function
|
||||
// they shouldn't be necessary anymore
|
||||
|
||||
// force stereo mode
|
||||
InjectCode((void*)0x0000000140A860C0, { 0x02 });
|
||||
|
||||
// remove a call to get device info and skip the check for it
|
||||
NopBytes((void*)0x140626b56, 7);
|
||||
NopBytes((void*)0x140626b8a, 8);
|
||||
InjectCode((void*)0x140626b8a, { 0x48, 0x83, 0xEF, 0x18 }); // fix value of RDI because I changed the flow here
|
||||
NopBytes((void*)0x140626ba9, 11);
|
||||
|
||||
// return from the original init early
|
||||
InjectCode((void*)0x0000000140626C29, { 0x48, 0xE9 });
|
||||
}
|
||||
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)divaAudioInit, (PVOID)hookedAudioInit);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
else if (ul_reason_for_call == DLL_PROCESS_DETACH)
|
||||
{
|
||||
if (useAsio) asioClose(); // this doesn't actually get called...
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include <miniaudio.h>
|
||||
#include <bassasio.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <audioclient.h>
|
||||
|
||||
void (__cdecl* divaAudioInit)(void* cls, uint64_t unk, uint64_t unk2) = (void(__cdecl*)(void* cls, uint64_t unk, uint64_t unk2))0x1406269F0;
|
||||
|
||||
void (__cdecl* divaAudioFillbuffer)(void* mixer, int16_t* buf, uint64_t nFrames, bool disableHpVol, bool invertPhase) = (void(__cdecl*)(void* mixer, int16_t* buf, uint64_t nFrames, bool disableHpVol, bool invertPhase))0x140627370;
|
||||
// mixer is a pointer to an audioMixer (from audio init's cls + 0x70)
|
||||
// disableHpVol uses speaker volume for headphones (only works in 4ch mode)
|
||||
// invertPhase inverts the output signal (only works if disableHpVol == false)
|
||||
|
||||
int (__cdecl* divaAudioAllocMixer)(void* cls, uint64_t unk, uint64_t unk2, int64_t nFrames) = (int(__cdecl*)(void* cls, uint64_t unk, uint64_t unk2, int64_t nFrames))0x140626710;
|
||||
// unks are the same as from the init call. they seem to set the internal mixing channel counts(?)
|
||||
// cls is the same as mixer in divaAudioFillbuffer
|
||||
// nFrames is number of audio frames to hold in the mixing buffers (only used when divaAudioFillbuffer is called). Internally this is multiplied by 16 (buffers are built using 32bit floats)
|
||||
|
||||
int(__cdecl* mtx_init)(void* mutex, int type) = (int(__cdecl*)(void* mutex, int type))0x14081DEF4;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct _50 {
|
||||
byte padding00[0x50];
|
||||
};
|
||||
struct _70 {
|
||||
byte padding00[0x70];
|
||||
};
|
||||
|
||||
struct streamingState {
|
||||
std::vector<_50>* state;
|
||||
float* buffer;
|
||||
uint64_t buffer_size;
|
||||
};
|
||||
|
||||
struct initClass;
|
||||
|
||||
struct audioMixer {
|
||||
initClass* audioClass;
|
||||
|
||||
std::vector<_70>** state1;
|
||||
uint64_t state1_len;
|
||||
streamingState* state2;
|
||||
uint64_t state2_len;
|
||||
|
||||
float* mixbuffer;
|
||||
uint64_t mixbuffer_size;
|
||||
|
||||
void* volume_mutex; // not sure if this is pointer or not
|
||||
float volume_master;
|
||||
float volume_channels[4];
|
||||
|
||||
byte padding54[4];
|
||||
};
|
||||
|
||||
struct initClass {
|
||||
WAVEFORMATEXTENSIBLE wave_format;
|
||||
IMMDeviceEnumerator *pEnumerator;
|
||||
IMMDevice *pDevice;
|
||||
IAudioClient *pAudioClient;
|
||||
|
||||
|
||||
uint64_t buffer_size;
|
||||
|
||||
IAudioRenderClient *pRenderClient;
|
||||
HANDLE hEvent;
|
||||
|
||||
uint64_t channels;
|
||||
uint64_t rate; // should always =44100
|
||||
uint64_t depth; // should always =16
|
||||
|
||||
audioMixer* mixer;
|
||||
|
||||
HANDLE hCallback;
|
||||
int32_t idk;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// known internal audio mixer variables (used by divaAudioFillbuffer and divaAudioAllocMixer)
|
||||
// cls + 0x00 = pointer to main audio/init class
|
||||
// cls + 0x08 = internal state 1 (SE?) vector pointer (or full class?)
|
||||
// cls + 0x10 = internal state 1 (SE?) length (channels?)
|
||||
// cls + 0x18 = internal state 2 (streaming?) vector pointer (or full class?)
|
||||
// cls + 0x20 = internal state 2 (streaming?) length (channels?)
|
||||
// cls + 0x28 = mixing buffer pointer (when a buffer is generated, this is filled with 32bit floats (four per frame)
|
||||
// cls + 0x30 = mixing buffer size (frame count * 16)
|
||||
//
|
||||
// cls + 0x38 = mutex lock for volume
|
||||
// cls + 0x40 = master volume float (multiply other volumes by this)
|
||||
// cls + 0x44 = ch1 volume
|
||||
// cls + 0x48 = ch2 volume
|
||||
// cls + 0x4c = ch3 volume
|
||||
// cls + 0x50 = ch4 volume
|
||||
//
|
||||
//
|
||||
// known main/init audio class variables (used by divaAudioInit)
|
||||
// cls + 0x0 = WAVEFORMATEXTENSIBLE wave_format (null with old method) (length 0x28)
|
||||
// cls + 0x28 = IMMDeviceEnumerator *pEnumerator
|
||||
// cls + 0x30 = IMMDevice *pDevice (default device)
|
||||
// cls + 0x38 = IAudioClient *pAudioClient
|
||||
//
|
||||
// cls + 0x40 = buffer size in frames (null with old method)
|
||||
//
|
||||
// cls + 0x48 = IAudioRenderClient *pRenderClient (null with old method)
|
||||
//
|
||||
// cls + 0x50 = HANDLE hEvent (for original WASAPI buffer timing) (null with old method)
|
||||
//
|
||||
// cls + 0x58 = number of output channels
|
||||
// cls + 0x60 = audio sample rate
|
||||
// cls + 0x68 = audio bit depth (only 16bit works)
|
||||
//
|
||||
// cls + 0x70 = pointer to mixer class
|
||||
//
|
||||
// cls + 0x78 = HANDLE hCallback (handle to original callback thread) (null with old method)
|
||||
|
||||
|
||||
initClass *divaAudCls;
|
||||
audioMixer *divaAudioMixCls;
|
||||
|
||||
std::thread loopThread;
|
||||
|
||||
ma_context_config contextConfig;
|
||||
ma_context context;
|
||||
ma_device_config deviceConfig;
|
||||
ma_device device;
|
||||
|
||||
int maInternalBufferSizeInMilliseconds;
|
||||
int divaBufSizeInFrames;
|
||||
int divaBufSizeInMilliseconds;
|
||||
|
||||
int nChannels; // this can only be 2 or 4
|
||||
int bitDepth; // signed 16/24 bit integer or 32 bit float
|
||||
int requestBuffer;
|
||||
int nPeriods;
|
||||
wchar_t backendName[32]; // wasapi or directsound
|
||||
ma_backend maBackend;
|
||||
ma_share_mode maSharemode;
|
||||
bool useAsio;
|
||||
int asioDevice;
|
||||
bool showAsioPanel;
|
||||
|
||||
bool useOldInit;
|
||||
|
||||
std::wstring ExePath() {
|
||||
WCHAR buffer[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
||||
return std::wstring(buffer);
|
||||
}
|
||||
|
||||
std::wstring DirPath() {
|
||||
std::wstring exepath = ExePath();
|
||||
std::wstring::size_type pos = exepath.find_last_of(L"\\/");
|
||||
return exepath.substr(0, pos);
|
||||
}
|
||||
|
||||
std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\DivaSound.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
|
||||
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
|
||||
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
||||
const IID IID_IAudioClient = __uuidof(IAudioClient);
|
||||
|
||||
#define SAFE_RELEASE(punk) \
|
||||
if ((punk) != NULL) \
|
||||
{ (punk)->Release(); (punk) = NULL; }
|
||||
@@ -12,6 +12,12 @@
|
||||
using namespace System;
|
||||
using namespace System::Windows::Forms;
|
||||
|
||||
float BaseScaleSize = 96;
|
||||
int Col1Width = 110;
|
||||
int Col2Left = 114;
|
||||
int Col2Width = 110;
|
||||
int ControlSpacing = 6;
|
||||
|
||||
// Custom function. Works like GetPrivateProfileIntW but returns bool. Can detect a numeric value or string.
|
||||
bool GetPrivateProfileBoolW(LPCWSTR lpAppName, LPCWSTR lpKeyName, bool default, LPCWSTR lpFileName)
|
||||
{
|
||||
@@ -220,16 +226,24 @@ public:
|
||||
|
||||
cb->Text = gcnew String(_friendlyName);
|
||||
cb->Checked = GetPrivateProfileBoolW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath);
|
||||
cb->Left = left;
|
||||
cb->Left = left + 2;
|
||||
cb->Top = top;
|
||||
cb->AutoSize = true;
|
||||
cb->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
cb->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(cb, gcnew String(_description));
|
||||
|
||||
panel->Controls->Add(cb);
|
||||
mainControlHandle = cb->Handle;
|
||||
return 23;
|
||||
|
||||
int ControlHeight = cb->Font->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
@@ -271,7 +285,7 @@ public:
|
||||
label->Text = gcnew String(_friendlyName);
|
||||
label->Left = left;
|
||||
label->Top = top + 3;
|
||||
label->Width = 100;
|
||||
label->Width = Col1Width;
|
||||
label->AutoSize = true;
|
||||
label->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
@@ -280,18 +294,27 @@ public:
|
||||
|
||||
numberbox->Value = (int)GetPrivateProfileIntW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath); // cast to int because this returns uint and breaks -1
|
||||
// it seems it does read negative values correctly though... but eventually a parser that properly supports negative numbers would be ideal
|
||||
numberbox->Left = left + 104;
|
||||
numberbox->Left = left + Col2Left;
|
||||
numberbox->Top = top;
|
||||
numberbox->Width = 90;
|
||||
numberbox->Width = Col2Width;
|
||||
numberbox->AutoSize = true;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
numberbox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(label, gcnew String(_description));
|
||||
tooltip->SetToolTip(numberbox, gcnew String(_description));
|
||||
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(numberbox);
|
||||
mainControlHandle = numberbox->Handle;
|
||||
return 28;
|
||||
|
||||
int ControlHeight = numberbox->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
@@ -334,7 +357,7 @@ public:
|
||||
label->Text = gcnew String(_friendlyName);
|
||||
label->Left = left;
|
||||
label->Top = top + 3;
|
||||
label->Width = 100;
|
||||
label->Width = Col1Width;
|
||||
label->AutoSize = true;
|
||||
label->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
@@ -345,11 +368,18 @@ public:
|
||||
}
|
||||
|
||||
textbox->Text = gcnew String(stringBuf);
|
||||
textbox->Left = left + 104;
|
||||
textbox->Left = left + Col2Left;
|
||||
textbox->Top = top;
|
||||
textbox->Width = 90;
|
||||
textbox->Width = Col2Width;
|
||||
textbox->AutoSize = true;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
textbox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
// disable editing for utf8 mode because the ANSI hack used may not work correctly
|
||||
if (_useUtf8) {
|
||||
textbox->Enabled = false;
|
||||
@@ -361,7 +391,9 @@ public:
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(textbox);
|
||||
mainControlHandle = textbox->Handle;
|
||||
return 28;
|
||||
|
||||
int ControlHeight = textbox->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
@@ -415,7 +447,7 @@ public:
|
||||
label->Text = gcnew String(_friendlyName);
|
||||
label->Left = left;
|
||||
label->Top = top + 3;
|
||||
label->Width = 100;
|
||||
label->Width = Col1Width;
|
||||
label->AutoSize = true;
|
||||
label->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
@@ -423,20 +455,29 @@ public:
|
||||
combobox->Items->Add(msclr::interop::marshal_as<System::String^>(choice));
|
||||
}
|
||||
combobox->SelectedIndex = GetPrivateProfileIntW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath);
|
||||
combobox->Left = left + 104;
|
||||
combobox->Left = left + Col2Left;
|
||||
combobox->Top = top;
|
||||
combobox->Width = 90;
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDownList;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(label, gcnew String(_description));
|
||||
tooltip->SetToolTip(combobox, gcnew String(_description));
|
||||
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(combobox);
|
||||
mainControlHandle = combobox->Handle;
|
||||
return 28;;
|
||||
|
||||
int ControlHeight = combobox->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
@@ -481,7 +522,7 @@ public:
|
||||
label->Text = gcnew String(_friendlyName);
|
||||
label->Left = left;
|
||||
label->Top = top + 3;
|
||||
label->Width = 100;
|
||||
label->Width = Col1Width;
|
||||
label->AutoSize = true;
|
||||
label->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
@@ -496,13 +537,20 @@ public:
|
||||
}
|
||||
|
||||
combobox->Text = gcnew String(stringBuf);
|
||||
combobox->Left = left + 104;
|
||||
combobox->Left = left + Col2Left;
|
||||
combobox->Top = top;
|
||||
combobox->Width = 90;
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
// disable editing for utf8 mode because the ANSI hack used may not work correctly
|
||||
if (_useUtf8) {
|
||||
label->Enabled = false;
|
||||
@@ -515,7 +563,9 @@ public:
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(combobox);
|
||||
mainControlHandle = combobox->Handle;
|
||||
return 28;;
|
||||
|
||||
int ControlHeight = combobox->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
@@ -571,7 +621,7 @@ public:
|
||||
label->Text = gcnew String(_friendlyName);
|
||||
label->Left = left;
|
||||
label->Top = top + 3;
|
||||
label->Width = 100;
|
||||
label->Width = Col1Width;
|
||||
label->AutoSize = true;
|
||||
label->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
@@ -582,13 +632,20 @@ public:
|
||||
tempSysStr = Convert::ToInt32((int)GetPrivateProfileIntW(_iniSectionName, _iniVarName, _defaultVal, _iniFilePath)).ToString();
|
||||
|
||||
combobox->Text = gcnew String(tempSysStr);
|
||||
combobox->Left = left + 104;
|
||||
combobox->Left = left + Col2Left;
|
||||
combobox->Top = top;
|
||||
combobox->Width = 90;
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(label, gcnew String(_description));
|
||||
tooltip->SetToolTip(combobox, gcnew String(_description));
|
||||
|
||||
@@ -598,7 +655,9 @@ public:
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(combobox);
|
||||
mainControlHandle = combobox->Handle;
|
||||
return 28;;
|
||||
|
||||
int ControlHeight = combobox->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
@@ -643,7 +702,7 @@ public:
|
||||
label->Text = gcnew String(_friendlyName);
|
||||
label->Left = left;
|
||||
label->Top = top + 3;
|
||||
label->Width = 100;
|
||||
label->Width = Col1Width;
|
||||
label->AutoSize = true;
|
||||
label->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
|
||||
@@ -663,13 +722,20 @@ public:
|
||||
combobox->Text = tempSysStr;
|
||||
}
|
||||
|
||||
combobox->Left = left + 104;
|
||||
combobox->Left = left + Col2Left;
|
||||
combobox->Top = top;
|
||||
combobox->Width = 90;
|
||||
combobox->Width = Col2Width;
|
||||
combobox->AutoSize = true;
|
||||
combobox->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
combobox->DropDownStyle = ComboBoxStyle::DropDown;
|
||||
|
||||
Form^ RootForm = panel->FindForm();
|
||||
Drawing::SizeF CurrentScaleSize = RootForm->CurrentAutoScaleDimensions;
|
||||
float ScaleWidth = CurrentScaleSize.Width / BaseScaleSize;
|
||||
float ScaleHeight = CurrentScaleSize.Height / BaseScaleSize;
|
||||
label->Scale(ScaleWidth, ScaleHeight);
|
||||
combobox->Scale(ScaleWidth, ScaleHeight);
|
||||
|
||||
tooltip->SetToolTip(label, gcnew String(_description));
|
||||
tooltip->SetToolTip(combobox, gcnew String(_description));
|
||||
|
||||
@@ -679,7 +745,9 @@ public:
|
||||
panel->Controls->Add(label);
|
||||
panel->Controls->Add(combobox);
|
||||
mainControlHandle = combobox->Handle;
|
||||
return 28;;
|
||||
|
||||
int ControlHeight = combobox->Height / ScaleHeight;
|
||||
return ControlHeight + ControlSpacing;
|
||||
}
|
||||
|
||||
virtual void SaveOption()
|
||||
|
||||
@@ -167,16 +167,22 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ConfigOption.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="SkinnedMessageBox.h" />
|
||||
<ClInclude Include="TabPadding.h" />
|
||||
<ClInclude Include="ui.h">
|
||||
<FileType>CppForm</FileType>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="SkinnedMessageBox.resx" />
|
||||
<EmbeddedResource Include="ui.resx">
|
||||
<DependentUpon>ui.h</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="PokeSnarf2x.bmp" />
|
||||
<Image Include="PokeSnarf2x.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
@@ -0,0 +1,394 @@
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Windows::Forms;
|
||||
using namespace System::Drawing;
|
||||
|
||||
// ported from https://stackoverflow.com/a/7785745
|
||||
// original code by user LarsTech https://stackoverflow.com/users/719186/larstech
|
||||
|
||||
static ref class SkinnedMessageBox
|
||||
{
|
||||
private: ref class SkinnedMessageBoxForm : Form
|
||||
{
|
||||
private:
|
||||
void SkinnedMessageBoxForm_Shown(Object^ sender, EventArgs^ e)
|
||||
{
|
||||
Activate();
|
||||
}
|
||||
|
||||
void SkinnedMessageBoxForm_FormClosed(Object^ sender, FormClosedEventArgs^ e)
|
||||
{
|
||||
if (CancelButton && (DialogResult == System::Windows::Forms::DialogResult::None || DialogResult == System::Windows::Forms::DialogResult::Cancel))
|
||||
DialogResult = CancelButton->DialogResult;
|
||||
}
|
||||
|
||||
void InitComponentNew()
|
||||
{
|
||||
this->SuspendLayout();
|
||||
|
||||
this->AutoSize = true;
|
||||
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog;
|
||||
this->Width = 350;
|
||||
this->Height = 140;
|
||||
this->StartPosition = FormStartPosition::CenterScreen;
|
||||
this->MaximizeBox = false;
|
||||
this->MinimizeBox = false;
|
||||
this->ShowInTaskbar = false;
|
||||
this->ShowIcon = false;
|
||||
__try
|
||||
{
|
||||
this->Icon = Application::OpenForms[0]->Icon;
|
||||
}
|
||||
__except (1) { }
|
||||
this->Shown += gcnew EventHandler(this, &SkinnedMessageBoxForm::SkinnedMessageBoxForm_Shown);
|
||||
this->FormClosed += gcnew FormClosedEventHandler(this, &SkinnedMessageBoxForm::SkinnedMessageBoxForm_FormClosed);
|
||||
|
||||
//this->Font = SystemFonts::MessageBoxFont;
|
||||
//this->Font = gcnew Font(SystemFonts::MessageBoxFont->FontFamily, SystemFonts::MessageBoxFont->SizeInPoints);
|
||||
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::None;
|
||||
|
||||
this->ResumeLayout(false);
|
||||
this->PerformLayout();
|
||||
}
|
||||
|
||||
float ScaleWidth = 1.0;
|
||||
float ScaleHeight = 1.0;
|
||||
int btnWidth = 85;
|
||||
int btnHeight = 23;
|
||||
int btnPadding = 12;
|
||||
|
||||
static cli::array<Button^>^ buttonrefs = gcnew cli::array<Button^>{ gcnew Button, gcnew Button, gcnew Button };
|
||||
int numbuttons = 1;
|
||||
|
||||
Button^ AddBtn(String^ text, System::Windows::Forms::DialogResult result, int btnNumber)
|
||||
{
|
||||
Button^ btn = buttonrefs[btnNumber];
|
||||
btn->Text = text;
|
||||
btn->DialogResult = result;
|
||||
btn->Anchor = AnchorStyles::Bottom | AnchorStyles::Right;
|
||||
btn->Width = btnWidth;
|
||||
btn->Height = btnHeight;
|
||||
|
||||
btn->Location = Point(ClientSize.Width - btnWidth * (numbuttons - btnNumber) - btnPadding * (numbuttons - btnNumber), ClientSize.Height - btnHeight - btnPadding);
|
||||
Controls->Add(btn);
|
||||
|
||||
//buttonrefs[btnNumber] = btn;
|
||||
return btn;
|
||||
}
|
||||
|
||||
void SetBackCol(Control^ elem, Color color)
|
||||
{
|
||||
Type^ elemType = elem->GetType();
|
||||
|
||||
if ((elem->HasChildren || elemType == Button::typeid || elemType == ComboBox::typeid) && elemType != NumericUpDown::typeid)
|
||||
{
|
||||
elem->BackColor = color;
|
||||
|
||||
for (int i = 0; i < elem->Controls->Count; i++)
|
||||
{
|
||||
SetBackCol(elem->Controls[i], color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetForeCol(Control^ elem, Color color)
|
||||
{
|
||||
Type^ elemType = elem->GetType();
|
||||
|
||||
if (elemType != NumericUpDown::typeid && elemType != TextBox::typeid)
|
||||
{
|
||||
elem->ForeColor = color;
|
||||
}
|
||||
if (elem->HasChildren && elemType != NumericUpDown::typeid)
|
||||
{
|
||||
for (int i = 0; i < elem->Controls->Count; i++)
|
||||
{
|
||||
SetForeCol(elem->Controls[i], color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetUIStyle(Control^ elem, FlatStyle style)
|
||||
{
|
||||
Type^ elemType = elem->GetType();
|
||||
|
||||
if (elemType == Button::typeid)
|
||||
{
|
||||
((Button^)elem)->FlatStyle = style;
|
||||
}
|
||||
else if (elemType == ComboBox::typeid)
|
||||
{
|
||||
((ComboBox^)elem)->FlatStyle = style;
|
||||
}
|
||||
else if (elemType == CheckBox::typeid)
|
||||
{
|
||||
((CheckBox^)elem)->FlatStyle = style;
|
||||
}
|
||||
|
||||
if (elem->HasChildren && elemType != NumericUpDown::typeid)
|
||||
{
|
||||
for (int i = 0; i < elem->Controls->Count; i++)
|
||||
{
|
||||
SetUIStyle(elem->Controls[i], style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
SkinnedMessageBoxForm(IWin32Window^ owner, String^ message, String^ caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultbutton, MessageBoxOptions options)
|
||||
{
|
||||
InitComponentNew();
|
||||
ScaleWidth = Font->SizeInPoints / 8.0f;
|
||||
ScaleHeight = ScaleWidth;
|
||||
btnWidth *= ScaleWidth;
|
||||
btnHeight *= ScaleHeight;
|
||||
btnPadding *= ScaleWidth;
|
||||
|
||||
Width *= ScaleWidth;
|
||||
Height *= ScaleHeight;
|
||||
|
||||
if (owner->Handle != IntPtr::Zero)
|
||||
{
|
||||
Owner = Control::FromHandle(owner->Handle)->FindForm();
|
||||
}
|
||||
else
|
||||
{
|
||||
Owner = ActiveForm;
|
||||
}
|
||||
|
||||
Text = caption;
|
||||
|
||||
System::Windows::Forms::Padding lblMargin = System::Windows::Forms::Padding(14 * ScaleWidth, 0 * ScaleHeight, 14 * ScaleWidth, 45 * ScaleHeight);
|
||||
Point lblLocation = Point(14 * ScaleWidth, 14 * ScaleHeight);
|
||||
Drawing::Size lblMinSize = Drawing::Size(ClientSize.Width - lblLocation.X - lblMargin.Right, 0);
|
||||
Drawing::Size lblMaxSize = Drawing::Size(600 * ScaleWidth, 0 * ScaleHeight);
|
||||
|
||||
Label^ MessageLbl = gcnew Label();
|
||||
MessageLbl->Text = message;
|
||||
MessageLbl->AutoSize = true;
|
||||
MessageLbl->Margin = lblMargin;
|
||||
MessageLbl->Location = lblLocation;
|
||||
MessageLbl->MinimumSize = lblMinSize;
|
||||
MessageLbl->MaximumSize = lblMaxSize;
|
||||
|
||||
Controls->Add(MessageLbl);
|
||||
|
||||
if (buttons == MessageBoxButtons::OK)
|
||||
{
|
||||
numbuttons = 1;
|
||||
Button^ OkBtn = AddBtn("&OK", System::Windows::Forms::DialogResult::OK, 0);
|
||||
CancelButton = OkBtn;
|
||||
//(not sure why, but this matches official .NET behaviour)
|
||||
}
|
||||
else if (buttons == MessageBoxButtons::OKCancel)
|
||||
{
|
||||
numbuttons = 2;
|
||||
AddBtn("&OK", System::Windows::Forms::DialogResult::OK, 0);
|
||||
Button^ CancelBtn = AddBtn("&Cancel", System::Windows::Forms::DialogResult::Cancel, 1);
|
||||
CancelButton = CancelBtn;
|
||||
}
|
||||
else if (buttons == MessageBoxButtons::YesNo)
|
||||
{
|
||||
numbuttons = 2;
|
||||
AddBtn("&Yes", System::Windows::Forms::DialogResult::Yes, 0);
|
||||
Button^ NoBtn = AddBtn("&No", System::Windows::Forms::DialogResult::No, 1);
|
||||
CancelButton = NoBtn;
|
||||
//(official .NET doesn't set cancel button, but this seems pretty clear to me...)
|
||||
}
|
||||
else if (buttons == MessageBoxButtons::RetryCancel)
|
||||
{
|
||||
numbuttons = 2;
|
||||
AddBtn("&Retry", System::Windows::Forms::DialogResult::Retry, 0);
|
||||
Button^ CancelBtn = AddBtn("&Cancel", System::Windows::Forms::DialogResult::Cancel, 1);
|
||||
CancelButton = CancelBtn;
|
||||
}
|
||||
else if (buttons == MessageBoxButtons::YesNoCancel)
|
||||
{
|
||||
numbuttons = 3;
|
||||
AddBtn("&Yes", System::Windows::Forms::DialogResult::Yes, 0);
|
||||
AddBtn("&No", System::Windows::Forms::DialogResult::No, 1);
|
||||
Button^ CancelBtn = AddBtn("&Cancel", System::Windows::Forms::DialogResult::Cancel, 2);
|
||||
CancelButton = CancelBtn;
|
||||
}
|
||||
else if (buttons == MessageBoxButtons::AbortRetryIgnore)
|
||||
{
|
||||
numbuttons = 3;
|
||||
AddBtn("&Abort", System::Windows::Forms::DialogResult::Abort, 0);
|
||||
AddBtn("&Retry", System::Windows::Forms::DialogResult::Retry, 1);
|
||||
AddBtn("&Ignore", System::Windows::Forms::DialogResult::Ignore, 2);
|
||||
//this.CancelButton = IgnoreBtn;
|
||||
//(official .NET doesn't set cancel button)
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::ComponentModel::InvalidEnumArgumentException("buttons", (int)buttons, MessageBoxButtons::typeid);
|
||||
}
|
||||
|
||||
if (!CancelButton)
|
||||
ControlBox = false;
|
||||
|
||||
|
||||
if (icon != MessageBoxIcon::None)
|
||||
{
|
||||
int iconsize = 32 * ScaleWidth;
|
||||
int iconpadding = 12 * ScaleWidth;
|
||||
int textpadding = -8 * ScaleWidth;
|
||||
|
||||
PictureBox^ iconPB = gcnew PictureBox();
|
||||
iconPB->Width = iconsize;
|
||||
iconPB->Height = iconsize;
|
||||
iconPB->Top = 10 * ScaleHeight;
|
||||
iconPB->Left = 10 * ScaleWidth;
|
||||
iconPB->AccessibleName = "Icon";
|
||||
|
||||
// there are many duplicated values:
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.messageboxicon?view=netframework-4.7.2
|
||||
if (icon == MessageBoxIcon::Error) // also Hand and Stop
|
||||
{
|
||||
Drawing::Icon^ erricon = gcnew Drawing::Icon(SystemIcons::Error, iconsize, iconsize);
|
||||
iconPB->Image = erricon->ToBitmap();
|
||||
iconPB->AccessibleDescription = "Error";
|
||||
//this.Icon = SystemIcons.Error;
|
||||
System::Media::SystemSounds::Hand->Play();
|
||||
}
|
||||
else if (icon == MessageBoxIcon::Question)
|
||||
{
|
||||
Drawing::Icon^ qicon = gcnew Drawing::Icon(SystemIcons::Question, iconsize, iconsize);
|
||||
iconPB->Image = qicon->ToBitmap();
|
||||
iconPB->AccessibleDescription = "Question";
|
||||
//this.Icon = SystemIcons.Question;
|
||||
System::Media::SystemSounds::Question->Play();
|
||||
}
|
||||
else if (icon == MessageBoxIcon::Warning) // also Exclamation
|
||||
{
|
||||
Drawing::Icon^ warnicon = gcnew Drawing::Icon(SystemIcons::Warning, iconsize, iconsize);
|
||||
iconPB->Image = warnicon->ToBitmap();
|
||||
//System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(SkinnedMessageBox::typeid));
|
||||
//iconPB->Image = cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"PokeSnarf2x"));
|
||||
iconPB->AccessibleDescription = "Warning";
|
||||
//this.Icon = SystemIcons.Warning;
|
||||
textpadding -= 2 * ScaleWidth; // triangle shape looks worse without this
|
||||
System::Media::SystemSounds::Exclamation->Play();
|
||||
}
|
||||
else if (icon == MessageBoxIcon::Information) // also Asterisk
|
||||
{
|
||||
Drawing::Icon^ infoicon = gcnew Drawing::Icon(SystemIcons::Information, iconsize, iconsize);
|
||||
iconPB->Image = infoicon->ToBitmap();
|
||||
iconPB->AccessibleDescription = "Information";
|
||||
//this.Icon = SystemIcons.Question;
|
||||
System::Media::SystemSounds::Asterisk->Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::ComponentModel::InvalidEnumArgumentException("icon", (int)icon, MessageBoxIcon::typeid);
|
||||
}
|
||||
|
||||
MessageLbl->MinimumSize = Drawing::Size(MessageLbl->MinimumSize.Width - (iconsize + iconpadding + textpadding), MessageLbl->MinimumSize.Height);
|
||||
MessageLbl->Left += (iconsize + iconpadding + textpadding);
|
||||
Controls->Add(iconPB);
|
||||
}
|
||||
|
||||
if (defaultbutton == MessageBoxDefaultButton::Button1)
|
||||
{
|
||||
AcceptButton = buttonrefs[0];
|
||||
ActiveControl = buttonrefs[0];
|
||||
}
|
||||
else if (defaultbutton == MessageBoxDefaultButton::Button2)
|
||||
{
|
||||
if (!Controls->Contains(buttonrefs[1])) throw gcnew ArgumentOutOfRangeException("defaultbutton", "defaultbutton cannot be set to a button number that does not exist");
|
||||
AcceptButton = buttonrefs[1];
|
||||
ActiveControl = buttonrefs[1];
|
||||
}
|
||||
else if (defaultbutton == MessageBoxDefaultButton::Button3)
|
||||
{
|
||||
if (!Controls->Contains(buttonrefs[2])) throw gcnew ArgumentOutOfRangeException("defaultbutton", "defaultbutton cannot be set to a button number that does not exist");
|
||||
AcceptButton = buttonrefs[2];
|
||||
ActiveControl = buttonrefs[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::ComponentModel::InvalidEnumArgumentException("defaultbutton", (int)defaultbutton, MessageBoxDefaultButton::typeid);
|
||||
}
|
||||
|
||||
|
||||
// TODO: TEXT ALIGNMENT AND RTL MODE
|
||||
/*
|
||||
// MessageBoxOptions are more like flags than concrete settings.
|
||||
// For ease of use, we assume default value is whatever winforms gives us in current locale -- but we override if any value is set
|
||||
if ((options & MessageBoxOptions.RightAlign) == MessageBoxOptions.RightAlign) MessageLbl.TextAlign = ContentAlignment.TopRight;
|
||||
else if (options != 0) MessageLbl.TextAlign = ContentAlignment.TopLeft;
|
||||
|
||||
// RtlReading should be what actually affects layout, and RightAlign only affects the text label
|
||||
if ((options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading)
|
||||
{
|
||||
foreach (Control control in this.Controls)
|
||||
{
|
||||
control.Left = this.ClientSize.Width - control.Right;
|
||||
control.RightToLeft = RightToLeft.Yes;
|
||||
}
|
||||
this.RightToLeft = RightToLeft.Yes;
|
||||
this.RightToLeftLayout = true;
|
||||
}
|
||||
else if (options != 0)
|
||||
{
|
||||
foreach (Control control in this.Controls)
|
||||
{
|
||||
control.RightToLeft = RightToLeft.No;
|
||||
}
|
||||
this.RightToLeft = RightToLeft.No;
|
||||
this.RightToLeftLayout = false;
|
||||
}
|
||||
*/
|
||||
|
||||
SetBackCol(this, Color::FromArgb(64, 64, 64));
|
||||
SetForeCol(this, Color::White);
|
||||
SetUIStyle(this, FlatStyle::Flat);
|
||||
}
|
||||
|
||||
SkinnedMessageBoxForm(String^ message, String^ caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultbutton, MessageBoxOptions options)
|
||||
{
|
||||
SkinnedMessageBoxForm(NativeWindow::FromHandle((IntPtr::Zero)), message, caption, buttons, icon, defaultbutton, options);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
static DialogResult Show(IWin32Window^ owner, String^ message, String^ caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultbutton, MessageBoxOptions options)
|
||||
{
|
||||
// I probably shouldn't do this, but from what I can tell this should be safe enough -- out of thread owner is allowed
|
||||
// and it only seems to appear when debugging (???)
|
||||
Control::CheckForIllegalCrossThreadCalls = false;
|
||||
SkinnedMessageBoxForm^ mb = gcnew SkinnedMessageBoxForm(owner, message, caption, buttons, icon, defaultbutton, options);
|
||||
DialogResult res = mb->ShowDialog();
|
||||
Control::CheckForIllegalCrossThreadCalls = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
static DialogResult Show(IWin32Window^ owner, String^ message, String^ caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultbutton)
|
||||
{
|
||||
return Show(owner, message, caption, buttons, icon, defaultbutton, (MessageBoxOptions)0);
|
||||
}
|
||||
|
||||
static DialogResult Show(IWin32Window^ owner, String^ message, String^ caption, MessageBoxButtons buttons, MessageBoxIcon icon)
|
||||
{
|
||||
return Show(owner, message, caption, buttons, icon, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0);
|
||||
}
|
||||
|
||||
static DialogResult Show(IWin32Window^ owner, String^ message, String^ caption, MessageBoxButtons buttons)
|
||||
{
|
||||
return Show(owner, message, caption, buttons, MessageBoxIcon::None, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0);
|
||||
}
|
||||
|
||||
static DialogResult Show(IWin32Window^ owner, String^ message, String^ caption)
|
||||
{
|
||||
return Show(owner, message, caption, MessageBoxButtons::OK, MessageBoxIcon::None, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0);
|
||||
}
|
||||
|
||||
static DialogResult Show(IWin32Window^ owner, String^ message)
|
||||
{
|
||||
return Show(owner, message, "", MessageBoxButtons::OK, MessageBoxIcon::None, MessageBoxDefaultButton::Button1, (MessageBoxOptions)0);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="PokeSnarf2x" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>PokeSnarf2x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 229 KiB |
@@ -8,8 +8,13 @@ using namespace System::Windows::Forms;
|
||||
|
||||
[STAThread]
|
||||
int showUI() {
|
||||
if (Environment::OSVersion->Version->Major >= 6)
|
||||
SetProcessDPIAware();
|
||||
SetProcessDPIAware();
|
||||
|
||||
// trick Optimus into switching to the NVIDIA GPU
|
||||
HMODULE nvcudaModule = LoadLibraryW(L"nvcuda.dll");
|
||||
// cuInit actually returns a CUresult, but we don't really care about it
|
||||
void(WINAPI * cuInit)(unsigned int flags) = (void(WINAPI*)(unsigned int flags))GetProcAddress(nvcudaModule, "cuInit");
|
||||
if (cuInit != NULL) cuInit(0);
|
||||
|
||||
Application::EnableVisualStyles();
|
||||
Application::SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 776 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
@@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
#include "framework.h"
|
||||
#include <msclr\marshal_cppstd.h>
|
||||
#include <cstdlib>
|
||||
#include "TabPadding.h"
|
||||
#include <GL\freeglut.h>
|
||||
#include <GL\GL.h>
|
||||
#include "SkinnedMessageBox.h"
|
||||
|
||||
namespace Launcher {
|
||||
|
||||
@@ -48,7 +51,7 @@ namespace Launcher {
|
||||
int screenresY = 3;
|
||||
for (ConfigOptionBase* option : screenResolutionArray)
|
||||
{
|
||||
screenresY += option->AddToPanel(panel_ScreenRes, 3, screenresY, toolTip1);
|
||||
screenresY += option->AddToPanel(panel_ScreenRes, 12, screenresY, toolTip1);
|
||||
}
|
||||
((ComboBox^)ComboBox::FromHandle(DisplayModeDropdown->mainControlHandle))->SelectedIndexChanged += gcnew System::EventHandler(this, &ui::DisplayTypeChangedHandler);
|
||||
DisplayTypeChangedHandler(this, gcnew EventArgs); // run handler now
|
||||
@@ -63,7 +66,7 @@ namespace Launcher {
|
||||
int intresY = 3;
|
||||
for (ConfigOptionBase* option : internalResolutionArray)
|
||||
{
|
||||
intresY += option->AddToPanel(panel_IntRes, 3, intresY, toolTip1);
|
||||
intresY += option->AddToPanel(panel_IntRes, 12, intresY, toolTip1);
|
||||
}
|
||||
((CheckBox^)CheckBox::FromHandle(InternalResolutionCheckbox->mainControlHandle))->CheckedChanged += gcnew System::EventHandler(this, &ui::InternalResEnabledChangedHandler);
|
||||
InternalResEnabledChangedHandler(this, gcnew EventArgs); // run handler now
|
||||
@@ -78,7 +81,7 @@ namespace Launcher {
|
||||
int optionsY = 3;
|
||||
for (ConfigOptionBase* option : optionsArray)
|
||||
{
|
||||
optionsY += option->AddToPanel(panel_Patches, 3, optionsY, toolTip1);
|
||||
optionsY += option->AddToPanel(panel_Patches, 12, optionsY, toolTip1);
|
||||
}
|
||||
this->panel_Patches->ResumeLayout(false);
|
||||
this->panel_Patches->PerformLayout();
|
||||
@@ -91,7 +94,7 @@ namespace Launcher {
|
||||
int playerdataY = 3;
|
||||
for (ConfigOptionBase* option : playerdataArray)
|
||||
{
|
||||
playerdataY += option->AddToPanel(panel_Playerdata, 3, playerdataY, toolTip1);
|
||||
playerdataY += option->AddToPanel(panel_Playerdata, 12, playerdataY, toolTip1);
|
||||
}
|
||||
this->panel_Playerdata->ResumeLayout(false);
|
||||
this->panel_Playerdata->PerformLayout();
|
||||
@@ -104,10 +107,28 @@ namespace Launcher {
|
||||
int componentsY = 3;
|
||||
for (ConfigOptionBase* component : componentsArray)
|
||||
{
|
||||
componentsY += component->AddToPanel(panel_Components, 3, componentsY, toolTip1);
|
||||
componentsY += component->AddToPanel(panel_Components, 12, componentsY, toolTip1);
|
||||
}
|
||||
this->panel_Components->ResumeLayout(false);
|
||||
this->panel_Components->PerformLayout();
|
||||
|
||||
int argc = 1;
|
||||
char* argv[1] = { (char*)"" };
|
||||
glutInit(&argc, argv);
|
||||
int window = glutCreateWindow("glut");
|
||||
String^ vendor = gcnew String((char*)glGetString(GL_VENDOR));
|
||||
String^ renderer = gcnew String((char*)glGetString(GL_RENDERER));
|
||||
String^ version = gcnew String((char*)glGetString(GL_VERSION));
|
||||
glutDestroyWindow(window);
|
||||
glutMainLoopEvent();
|
||||
/*MessageBox::Show(vendor, "vendor", MessageBoxButtons::OK, MessageBoxIcon::Information);
|
||||
MessageBox::Show(renderer, "renderer", MessageBoxButtons::OK, MessageBoxIcon::Information);
|
||||
MessageBox::Show(version, "version", MessageBoxButtons::OK, MessageBoxIcon::Information);*/
|
||||
this->labelGPU->Text = "Vendor: " + vendor + "\nRenderer: " + renderer + "\nOpenGL: " + version;
|
||||
if (vendor != "NVIDIA Corporation")
|
||||
//MessageBox::Show("Your graphics card is not supported! Only NVIDIA GPUs are currently supported.", "PD Launcher", MessageBoxButtons::OK, MessageBoxIcon::Error);
|
||||
SkinnedMessageBox::Show(this, "Your graphics card is not supported! Only NVIDIA GPUs are currently supported.", "PD Launcher", MessageBoxButtons::OK, MessageBoxIcon::Warning);
|
||||
//if (version[0] < 4) MessageBox::Show("WARNING: Your GPU is too old. The game might not render correctly!", "PD Launcher", MessageBoxButtons::OK, MessageBoxIcon::Warning);
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -122,7 +143,8 @@ namespace Launcher {
|
||||
}
|
||||
}
|
||||
private: System::Windows::Forms::Button^ button_Launch;
|
||||
private: System::Windows::Forms::Button^ button_Exit;
|
||||
private: System::Windows::Forms::Button^ button_Help;
|
||||
|
||||
private: System::Windows::Forms::GroupBox^ groupBox_ScreenRes;
|
||||
private: System::Windows::Forms::TabControl^ tabControl;
|
||||
private: System::Windows::Forms::TabPage^ tabPage_Resolution;
|
||||
@@ -138,7 +160,11 @@ namespace Launcher {
|
||||
private: System::Windows::Forms::ToolTip^ toolTip1;
|
||||
private: System::Windows::Forms::Panel^ panel_ScreenRes;
|
||||
private: System::Windows::Forms::Panel^ panel_IntRes;
|
||||
private: System::ComponentModel::IContainer^ components;
|
||||
private: System::Windows::Forms::Label^ labelGPU;
|
||||
|
||||
|
||||
|
||||
private: System::ComponentModel::IContainer^ components;
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
@@ -154,13 +180,14 @@ namespace Launcher {
|
||||
void InitializeComponent(void)
|
||||
{
|
||||
this->components = (gcnew System::ComponentModel::Container());
|
||||
System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(ui::typeid));
|
||||
System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(ui::typeid));
|
||||
this->button_Launch = (gcnew System::Windows::Forms::Button());
|
||||
this->button_Exit = (gcnew System::Windows::Forms::Button());
|
||||
this->button_Help = (gcnew System::Windows::Forms::Button());
|
||||
this->groupBox_ScreenRes = (gcnew System::Windows::Forms::GroupBox());
|
||||
this->panel_ScreenRes = (gcnew System::Windows::Forms::Panel());
|
||||
this->tabControl = (gcnew System::Windows::Forms::TabControl());
|
||||
this->tabPage_Resolution = (gcnew System::Windows::Forms::TabPage());
|
||||
this->labelGPU = (gcnew System::Windows::Forms::Label());
|
||||
this->groupBox_InternalRes = (gcnew System::Windows::Forms::GroupBox());
|
||||
this->panel_IntRes = (gcnew System::Windows::Forms::Panel());
|
||||
this->tabPage_Patches = (gcnew System::Windows::Forms::TabPage());
|
||||
@@ -185,42 +212,48 @@ namespace Launcher {
|
||||
//
|
||||
this->button_Launch->FlatAppearance->BorderColor = System::Drawing::SystemColors::Control;
|
||||
this->button_Launch->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->button_Launch->Location = System::Drawing::Point(18, 267);
|
||||
this->button_Launch->Location = System::Drawing::Point(25, 473);
|
||||
this->button_Launch->Margin = System::Windows::Forms::Padding(4);
|
||||
this->button_Launch->Name = L"button_Launch";
|
||||
this->button_Launch->Size = System::Drawing::Size(75, 23);
|
||||
this->button_Launch->Size = System::Drawing::Size(112, 34);
|
||||
this->button_Launch->TabIndex = 20;
|
||||
this->button_Launch->Text = L"Launch";
|
||||
this->button_Launch->Click += gcnew System::EventHandler(this, &ui::Button_Launch_Click);
|
||||
//
|
||||
// button_Exit
|
||||
// button_Help
|
||||
//
|
||||
this->button_Exit->DialogResult = System::Windows::Forms::DialogResult::Cancel;
|
||||
this->button_Exit->FlatAppearance->BorderColor = System::Drawing::SystemColors::Control;
|
||||
this->button_Exit->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->button_Exit->Location = System::Drawing::Point(139, 267);
|
||||
this->button_Exit->Name = L"button_Exit";
|
||||
this->button_Exit->Size = System::Drawing::Size(75, 23);
|
||||
this->button_Exit->TabIndex = 21;
|
||||
this->button_Exit->Text = L"Exit";
|
||||
this->button_Exit->Click += gcnew System::EventHandler(this, &ui::Button_Exit_Click);
|
||||
this->button_Help->DialogResult = System::Windows::Forms::DialogResult::Cancel;
|
||||
this->button_Help->FlatAppearance->BorderColor = System::Drawing::SystemColors::Control;
|
||||
this->button_Help->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->button_Help->Location = System::Drawing::Point(151, 473);
|
||||
this->button_Help->Margin = System::Windows::Forms::Padding(4);
|
||||
this->button_Help->Name = L"button_Help";
|
||||
this->button_Help->Size = System::Drawing::Size(112, 34);
|
||||
this->button_Help->TabIndex = 21;
|
||||
this->button_Help->Text = L"Get help";
|
||||
this->button_Help->Click += gcnew System::EventHandler(this, &ui::Button_Help_Click);
|
||||
//
|
||||
// groupBox_ScreenRes
|
||||
//
|
||||
this->groupBox_ScreenRes->Controls->Add(this->panel_ScreenRes);
|
||||
this->groupBox_ScreenRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->groupBox_ScreenRes->ForeColor = System::Drawing::Color::White;
|
||||
this->groupBox_ScreenRes->Location = System::Drawing::Point(8, 6);
|
||||
this->groupBox_ScreenRes->Location = System::Drawing::Point(8, 9);
|
||||
this->groupBox_ScreenRes->Margin = System::Windows::Forms::Padding(4);
|
||||
this->groupBox_ScreenRes->Name = L"groupBox_ScreenRes";
|
||||
this->groupBox_ScreenRes->Size = System::Drawing::Size(208, 133);
|
||||
this->groupBox_ScreenRes->Padding = System::Windows::Forms::Padding(4);
|
||||
this->groupBox_ScreenRes->Size = System::Drawing::Size(417, 205);
|
||||
this->groupBox_ScreenRes->TabIndex = 10;
|
||||
this->groupBox_ScreenRes->TabStop = false;
|
||||
this->groupBox_ScreenRes->Text = L"Screen Resolution";
|
||||
//
|
||||
// panel_ScreenRes
|
||||
//
|
||||
this->panel_ScreenRes->Location = System::Drawing::Point(4, 19);
|
||||
this->panel_ScreenRes->AutoScroll = true;
|
||||
this->panel_ScreenRes->Location = System::Drawing::Point(6, 28);
|
||||
this->panel_ScreenRes->Margin = System::Windows::Forms::Padding(4);
|
||||
this->panel_ScreenRes->Name = L"panel_ScreenRes";
|
||||
this->panel_ScreenRes->Size = System::Drawing::Size(200, 108);
|
||||
this->panel_ScreenRes->Size = System::Drawing::Size(403, 169);
|
||||
this->panel_ScreenRes->TabIndex = 0;
|
||||
//
|
||||
// tabControl
|
||||
@@ -231,41 +264,59 @@ namespace Launcher {
|
||||
this->tabControl->Controls->Add(this->tabPage_Playerdata);
|
||||
this->tabControl->Controls->Add(this->tabPage_Components);
|
||||
this->tabControl->Location = System::Drawing::Point(0, 0);
|
||||
this->tabControl->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabControl->Name = L"tabControl";
|
||||
this->tabControl->SelectedIndex = 0;
|
||||
this->tabControl->Size = System::Drawing::Size(233, 261);
|
||||
this->tabControl->Size = System::Drawing::Size(441, 465);
|
||||
this->tabControl->TabIndex = 10;
|
||||
//
|
||||
// tabPage_Resolution
|
||||
//
|
||||
this->tabPage_Resolution->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Resolution->BackColor = System::Drawing::Color::Transparent;
|
||||
this->tabPage_Resolution->BackgroundImage = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"tabPage_Resolution.BackgroundImage")));
|
||||
this->tabPage_Resolution->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Stretch;
|
||||
this->tabPage_Resolution->Controls->Add(this->labelGPU);
|
||||
this->tabPage_Resolution->Controls->Add(this->groupBox_InternalRes);
|
||||
this->tabPage_Resolution->Controls->Add(this->groupBox_ScreenRes);
|
||||
this->tabPage_Resolution->Location = System::Drawing::Point(4, 25);
|
||||
this->tabPage_Resolution->Location = System::Drawing::Point(4, 32);
|
||||
this->tabPage_Resolution->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Resolution->Name = L"tabPage_Resolution";
|
||||
this->tabPage_Resolution->Padding = System::Windows::Forms::Padding(3);
|
||||
this->tabPage_Resolution->Size = System::Drawing::Size(225, 232);
|
||||
this->tabPage_Resolution->Padding = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Resolution->Size = System::Drawing::Size(433, 429);
|
||||
this->tabPage_Resolution->TabIndex = 0;
|
||||
this->tabPage_Resolution->Text = L"Resolution";
|
||||
//
|
||||
// labelGPU
|
||||
//
|
||||
this->labelGPU->AutoSize = true;
|
||||
this->labelGPU->Location = System::Drawing::Point(12, 359);
|
||||
this->labelGPU->MinimumSize = System::Drawing::Size(410, 20);
|
||||
this->labelGPU->Name = L"labelGPU";
|
||||
this->labelGPU->Size = System::Drawing::Size(410, 20);
|
||||
this->labelGPU->TabIndex = 21;
|
||||
this->labelGPU->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
|
||||
//
|
||||
// groupBox_InternalRes
|
||||
//
|
||||
this->groupBox_InternalRes->Controls->Add(this->panel_IntRes);
|
||||
this->groupBox_InternalRes->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->groupBox_InternalRes->ForeColor = System::Drawing::Color::White;
|
||||
this->groupBox_InternalRes->Location = System::Drawing::Point(8, 145);
|
||||
this->groupBox_InternalRes->Location = System::Drawing::Point(8, 222);
|
||||
this->groupBox_InternalRes->Margin = System::Windows::Forms::Padding(4);
|
||||
this->groupBox_InternalRes->Name = L"groupBox_InternalRes";
|
||||
this->groupBox_InternalRes->Size = System::Drawing::Size(208, 83);
|
||||
this->groupBox_InternalRes->Padding = System::Windows::Forms::Padding(4);
|
||||
this->groupBox_InternalRes->Size = System::Drawing::Size(417, 124);
|
||||
this->groupBox_InternalRes->TabIndex = 20;
|
||||
this->groupBox_InternalRes->TabStop = false;
|
||||
this->groupBox_InternalRes->Text = L"Internal Resolution";
|
||||
//
|
||||
// panel_IntRes
|
||||
//
|
||||
this->panel_IntRes->Location = System::Drawing::Point(4, 19);
|
||||
this->panel_IntRes->AutoScroll = true;
|
||||
this->panel_IntRes->Location = System::Drawing::Point(6, 28);
|
||||
this->panel_IntRes->Margin = System::Windows::Forms::Padding(4);
|
||||
this->panel_IntRes->Name = L"panel_IntRes";
|
||||
this->panel_IntRes->Size = System::Drawing::Size(200, 58);
|
||||
this->panel_IntRes->Size = System::Drawing::Size(403, 88);
|
||||
this->panel_IntRes->TabIndex = 1;
|
||||
//
|
||||
// tabPage_Patches
|
||||
@@ -273,9 +324,10 @@ namespace Launcher {
|
||||
this->tabPage_Patches->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Patches->Controls->Add(this->panel_Patches);
|
||||
this->tabPage_Patches->Location = System::Drawing::Point(4, 25);
|
||||
this->tabPage_Patches->Location = System::Drawing::Point(4, 32);
|
||||
this->tabPage_Patches->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Patches->Name = L"tabPage_Patches";
|
||||
this->tabPage_Patches->Size = System::Drawing::Size(225, 232);
|
||||
this->tabPage_Patches->Size = System::Drawing::Size(433, 429);
|
||||
this->tabPage_Patches->TabIndex = 1;
|
||||
this->tabPage_Patches->Text = L"Options";
|
||||
//
|
||||
@@ -283,18 +335,20 @@ namespace Launcher {
|
||||
//
|
||||
this->panel_Patches->AutoScroll = true;
|
||||
this->panel_Patches->Location = System::Drawing::Point(0, 0);
|
||||
this->panel_Patches->Margin = System::Windows::Forms::Padding(4);
|
||||
this->panel_Patches->Name = L"panel_Patches";
|
||||
this->panel_Patches->Size = System::Drawing::Size(225, 232);
|
||||
this->panel_Patches->Size = System::Drawing::Size(429, 425);
|
||||
this->panel_Patches->TabIndex = 9;
|
||||
//
|
||||
// tabPage_Playerdata
|
||||
//
|
||||
this->tabPage_Playerdata->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Playerdata->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Playerdata->Controls->Add(this->panel_Playerdata);
|
||||
this->tabPage_Playerdata->Location = System::Drawing::Point(4, 25);
|
||||
this->tabPage_Playerdata->Location = System::Drawing::Point(4, 32);
|
||||
this->tabPage_Playerdata->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Playerdata->Name = L"tabPage_Playerdata";
|
||||
this->tabPage_Playerdata->Size = System::Drawing::Size(225, 232);
|
||||
this->tabPage_Playerdata->Size = System::Drawing::Size(433, 429);
|
||||
this->tabPage_Playerdata->TabIndex = 3;
|
||||
this->tabPage_Playerdata->Text = L"Player Data";
|
||||
//
|
||||
@@ -302,19 +356,21 @@ namespace Launcher {
|
||||
//
|
||||
this->panel_Playerdata->AutoScroll = true;
|
||||
this->panel_Playerdata->Location = System::Drawing::Point(0, 0);
|
||||
this->panel_Playerdata->Margin = System::Windows::Forms::Padding(4);
|
||||
this->panel_Playerdata->Name = L"panel_Playerdata";
|
||||
this->panel_Playerdata->Size = System::Drawing::Size(225, 232);
|
||||
this->panel_Playerdata->Size = System::Drawing::Size(429, 425);
|
||||
this->panel_Playerdata->TabIndex = 1;
|
||||
//
|
||||
// tabPage_Components
|
||||
//
|
||||
this->tabPage_Components->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Components->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->tabPage_Components->Controls->Add(this->panel_Components);
|
||||
this->tabPage_Components->Location = System::Drawing::Point(4, 25);
|
||||
this->tabPage_Components->Location = System::Drawing::Point(4, 32);
|
||||
this->tabPage_Components->Margin = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Components->Name = L"tabPage_Components";
|
||||
this->tabPage_Components->Padding = System::Windows::Forms::Padding(3);
|
||||
this->tabPage_Components->Size = System::Drawing::Size(225, 232);
|
||||
this->tabPage_Components->Padding = System::Windows::Forms::Padding(4);
|
||||
this->tabPage_Components->Size = System::Drawing::Size(433, 429);
|
||||
this->tabPage_Components->TabIndex = 2;
|
||||
this->tabPage_Components->Text = L"Components";
|
||||
//
|
||||
@@ -322,8 +378,9 @@ namespace Launcher {
|
||||
//
|
||||
this->panel_Components->AutoScroll = true;
|
||||
this->panel_Components->Location = System::Drawing::Point(0, 0);
|
||||
this->panel_Components->Margin = System::Windows::Forms::Padding(4);
|
||||
this->panel_Components->Name = L"panel_Components";
|
||||
this->panel_Components->Size = System::Drawing::Size(225, 232);
|
||||
this->panel_Components->Size = System::Drawing::Size(429, 425);
|
||||
this->panel_Components->TabIndex = 0;
|
||||
//
|
||||
// button_Discord
|
||||
@@ -334,9 +391,10 @@ namespace Launcher {
|
||||
this->button_Discord->FlatAppearance->MouseOverBackColor = System::Drawing::Color::Transparent;
|
||||
this->button_Discord->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->button_Discord->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"button_Discord.Image")));
|
||||
this->button_Discord->Location = System::Drawing::Point(239, 12);
|
||||
this->button_Discord->Location = System::Drawing::Point(295, 459);
|
||||
this->button_Discord->Margin = System::Windows::Forms::Padding(4);
|
||||
this->button_Discord->Name = L"button_Discord";
|
||||
this->button_Discord->Size = System::Drawing::Size(42, 42);
|
||||
this->button_Discord->Size = System::Drawing::Size(63, 63);
|
||||
this->button_Discord->TabIndex = 31;
|
||||
this->button_Discord->UseVisualStyleBackColor = false;
|
||||
this->button_Discord->Click += gcnew System::EventHandler(this, &ui::button_Discord_Click);
|
||||
@@ -344,14 +402,16 @@ namespace Launcher {
|
||||
// button_github
|
||||
//
|
||||
this->button_github->BackColor = System::Drawing::Color::Transparent;
|
||||
this->button_github->Cursor = System::Windows::Forms::Cursors::Hand;
|
||||
this->button_github->FlatAppearance->BorderSize = 0;
|
||||
this->button_github->FlatAppearance->MouseDownBackColor = System::Drawing::Color::Transparent;
|
||||
this->button_github->FlatAppearance->MouseOverBackColor = System::Drawing::Color::Transparent;
|
||||
this->button_github->FlatStyle = System::Windows::Forms::FlatStyle::Flat;
|
||||
this->button_github->Image = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"button_github.Image")));
|
||||
this->button_github->Location = System::Drawing::Point(239, 60);
|
||||
this->button_github->Location = System::Drawing::Point(378, 459);
|
||||
this->button_github->Margin = System::Windows::Forms::Padding(4);
|
||||
this->button_github->Name = L"button_github";
|
||||
this->button_github->Size = System::Drawing::Size(42, 42);
|
||||
this->button_github->Size = System::Drawing::Size(63, 63);
|
||||
this->button_github->TabIndex = 32;
|
||||
this->button_github->UseVisualStyleBackColor = false;
|
||||
this->button_github->Click += gcnew System::EventHandler(this, &ui::button_github_Click);
|
||||
@@ -359,24 +419,24 @@ namespace Launcher {
|
||||
// ui
|
||||
//
|
||||
this->AcceptButton = this->button_Launch;
|
||||
this->AutoScaleDimensions = System::Drawing::SizeF(96, 96);
|
||||
this->AutoScaleDimensions = System::Drawing::SizeF(144, 144);
|
||||
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Dpi;
|
||||
this->AutoSize = true;
|
||||
this->AutoSizeMode = System::Windows::Forms::AutoSizeMode::GrowAndShrink;
|
||||
this->BackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(64)),
|
||||
static_cast<System::Int32>(static_cast<System::Byte>(64)));
|
||||
this->BackgroundImage = (cli::safe_cast<System::Drawing::Image^>(resources->GetObject(L"$this.BackgroundImage")));
|
||||
this->BackgroundImageLayout = System::Windows::Forms::ImageLayout::Stretch;
|
||||
this->CancelButton = this->button_Exit;
|
||||
this->ClientSize = System::Drawing::Size(288, 297);
|
||||
this->ClientSize = System::Drawing::Size(440, 514);
|
||||
this->Controls->Add(this->tabControl);
|
||||
this->Controls->Add(this->button_Help);
|
||||
this->Controls->Add(this->button_Launch);
|
||||
this->Controls->Add(this->button_github);
|
||||
this->Controls->Add(this->button_Discord);
|
||||
this->Controls->Add(this->tabControl);
|
||||
this->Controls->Add(this->button_Exit);
|
||||
this->Controls->Add(this->button_Launch);
|
||||
this->DoubleBuffered = true;
|
||||
this->ForeColor = System::Drawing::Color::White;
|
||||
this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedDialog;
|
||||
this->Icon = (cli::safe_cast<System::Drawing::Icon^>(resources->GetObject(L"$this.Icon")));
|
||||
this->Margin = System::Windows::Forms::Padding(4);
|
||||
this->MaximizeBox = false;
|
||||
this->MinimizeBox = false;
|
||||
this->Name = L"ui";
|
||||
@@ -388,6 +448,7 @@ namespace Launcher {
|
||||
this->groupBox_ScreenRes->ResumeLayout(false);
|
||||
this->tabControl->ResumeLayout(false);
|
||||
this->tabPage_Resolution->ResumeLayout(false);
|
||||
this->tabPage_Resolution->PerformLayout();
|
||||
this->groupBox_InternalRes->ResumeLayout(false);
|
||||
this->tabPage_Patches->ResumeLayout(false);
|
||||
this->tabPage_Playerdata->ResumeLayout(false);
|
||||
@@ -424,8 +485,8 @@ private: System::Void SaveSettings() {
|
||||
}
|
||||
private: System::Void Ui_Load(System::Object^ sender, System::EventArgs^ e){
|
||||
}
|
||||
private: System::Void Button_Exit_Click(System::Object^ sender, System::EventArgs^ e) {
|
||||
this->Close();
|
||||
private: System::Void Button_Help_Click(System::Object^ sender, System::EventArgs^ e) {
|
||||
System::Diagnostics::Process::Start("https://notabug.org/nastys/PD-Loader/wiki");
|
||||
}
|
||||
private: System::Void Button_Launch_Click(System::Object^ sender, System::EventArgs^ e) {
|
||||
|
||||
|
||||
+19572
-4267
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,14 @@
|
||||
|
||||
int hookedCreateWindow(const char* title, void(__cdecl* exit_function)(int))
|
||||
{
|
||||
SetProcessDPIAware();
|
||||
|
||||
// trick Optimus into switching to the NVIDIA GPU
|
||||
HMODULE nvcudaModule = LoadLibraryW(L"nvcuda.dll");
|
||||
// cuInit actually returns a CUresult, but we don't really care about it
|
||||
void(WINAPI * cuInit)(unsigned int flags) = (void(WINAPI*)(unsigned int flags))GetProcAddress(nvcudaModule, "cuInit");
|
||||
if (cuInit != NULL) cuInit(0);
|
||||
|
||||
if (nDisplay == 1) // borderless fullscreen
|
||||
{
|
||||
*fullScreenFlag = 0;
|
||||
|
||||
Reference in New Issue
Block a user