mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-26 09:41:03 +00:00
Added a Win32 GDI visualizer.
This commit is contained in:
parent
02282e4991
commit
f672446ebf
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,6 +7,8 @@
|
||||
**/Makefile
|
||||
**/cmake_install.cmake
|
||||
**/install_manifest.txt
|
||||
**/Release
|
||||
**/Debug
|
||||
.vs
|
||||
.vscode
|
||||
bin
|
||||
|
@ -4,6 +4,7 @@ VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "musikbox", "src\musikbox\musikbox.vcxproj", "{C7102EB1-7311-4B36-A7FF-89DD7F077FF9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{68AA481E-3CCE-440F-8CCE-69F1B371C89D} = {68AA481E-3CCE-440F-8CCE-69F1B371C89D}
|
||||
{3E30064E-B9C4-4690-8AC2-2C694176A319} = {3E30064E-B9C4-4690-8AC2-2C694176A319}
|
||||
{54764854-5A73-4329-9BAD-9AF22C72D9E2} = {54764854-5A73-4329-9BAD-9AF22C72D9E2}
|
||||
{465EF178-91C1-4068-BE1D-F9616ECCB6DE} = {465EF178-91C1-4068-BE1D-F9616ECCB6DE}
|
||||
@ -34,6 +35,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "m4adecoder", "src\contrib\m
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win32globalhotkeys", "src\contrib\win32globalhotkeys\win32globalhotkeys.vcxproj", "{3E30064E-B9C4-4690-8AC2-2C694176A319}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win32gdivis", "src\contrib\win32gdivis\GdiVis-musikcube.vcxproj", "{68AA481E-3CCE-440F-8CCE-69F1B371C89D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@ -84,6 +87,10 @@ Global
|
||||
{3E30064E-B9C4-4690-8AC2-2C694176A319}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3E30064E-B9C4-4690-8AC2-2C694176A319}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3E30064E-B9C4-4690-8AC2-2C694176A319}.Release|Win32.Build.0 = Release|Win32
|
||||
{68AA481E-3CCE-440F-8CCE-69F1B371C89D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{68AA481E-3CCE-440F-8CCE-69F1B371C89D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{68AA481E-3CCE-440F-8CCE-69F1B371C89D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{68AA481E-3CCE-440F-8CCE-69F1B371C89D}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -36,16 +36,16 @@
|
||||
#include "CddaDataStream.h"
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <mutex>
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define MSF2UINT(hgs) ((hgs[1]*4500) + (hgs[2]*75) + (hgs[3]))
|
||||
|
||||
static CddaDataStream* active = NULL;
|
||||
static boost::mutex activeMutex;
|
||||
static std::mutex activeMutex;
|
||||
|
||||
static void setActive(CddaDataStream* stream) {
|
||||
boost::mutex::scoped_lock lock(activeMutex);
|
||||
std::unique_lock<std::mutex> lock(activeMutex);
|
||||
|
||||
if (active != NULL) {
|
||||
active->Close();
|
||||
@ -56,7 +56,7 @@ static void setActive(CddaDataStream* stream) {
|
||||
}
|
||||
|
||||
static void resetIfActive(CddaDataStream* stream) {
|
||||
boost::mutex::scoped_lock lock(activeMutex);
|
||||
std::unique_lock<std::mutex> lock(activeMutex);
|
||||
|
||||
if (stream == active) {
|
||||
active = NULL;
|
||||
|
@ -54,7 +54,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../../;../../3rdparty/include;../../../../boost_1_60_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../;../../3rdparty/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@ -76,7 +76,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>../../;../../3rdparty/include;../../../../boost_1_60_0;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../;../../3rdparty/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
|
157
src/contrib/win32gdivis/GdiVis-musikcube.vcxproj
Normal file
157
src/contrib/win32gdivis/GdiVis-musikcube.vcxproj
Normal file
@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="v140" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GdiVis.cpp" />
|
||||
<ClCompile Include="MemoryDC.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MemoryDC.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<SccProjectName />
|
||||
<SccLocalPath />
|
||||
<ProjectGuid>{68AA481E-3CCE-440F-8CCE-69F1B371C89D}</ProjectGuid>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>win32gdivis</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)bin\release\</OutDir>
|
||||
<IntDir>.\Release\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)bin\debug\</OutDir>
|
||||
<IntDir>.\Debug\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<StringPooling>true</StringPooling>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<AdditionalIncludeDirectories>.\;..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>.\Release\</AssemblerListingLocation>
|
||||
<PrecompiledHeaderOutputFile>.\Release\projectMvis.pch</PrecompiledHeaderOutputFile>
|
||||
<ObjectFileName>.\Release\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Release\</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Release\projectMvis.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Release\projectMvis.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(SolutionDir)bin\release\win32gdivis.dll</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)bin\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>LIBCMT.LIB;version.lib;winmm.lib;Imm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy $(TargetPath) $(SolutionDir)\bin\release\plugins\ /Y
|
||||
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>.\;..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>.\Debug\</AssemblerListingLocation>
|
||||
<PrecompiledHeaderOutputFile>.\Debug\projectMvis.pch</PrecompiledHeaderOutputFile>
|
||||
<ObjectFileName>.\Debug\</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\Debug\</ProgramDataBaseFileName>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
</ClCompile>
|
||||
<Midl>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<TypeLibraryName>.\Debug\projectMvis.tlb</TypeLibraryName>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<Culture>0x0409</Culture>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Bscmake>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<OutputFile>.\Debug\projectMvis.bsc</OutputFile>
|
||||
</Bscmake>
|
||||
<Link>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OutputFile>$(SolutionDir)bin\debug\win32gdivis.dll</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)bin\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>LIBCMTD.LIB;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy $(TargetPath) $(SolutionDir)\bin\debug\plugins\ /Y
|
||||
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
22
src/contrib/win32gdivis/GdiVis-musikcube.vcxproj.filters
Normal file
22
src/contrib/win32gdivis/GdiVis-musikcube.vcxproj.filters
Normal file
@ -0,0 +1,22 @@
|
||||
<?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>{4af6aad0-9c71-4dc2-8343-19c467346884}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="GdiVis.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MemoryDC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="MemoryDC.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
311
src/contrib/win32gdivis/GdiVis.cpp
Normal file
311
src/contrib/win32gdivis/GdiVis.cpp
Normal file
@ -0,0 +1,311 @@
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include <core/sdk/ISpectrumVisualizer.h>
|
||||
#include <core/sdk/IPlugin.h>
|
||||
|
||||
#include "MemoryDC.h"
|
||||
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
#define MAX_FPS 10LL
|
||||
#define MILLIS_PER_FRAME (1000LL / MAX_FPS)
|
||||
#define WINDOW_CLASS_NAME L"GdiVis-musikcube"
|
||||
#define DEFAULT_WIDTH 550
|
||||
#define DEFAULT_HEIGHT 120
|
||||
#define TEXTURE_WIDTH 90
|
||||
#define TEXTURE_HEIGHT 80
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
static std::atomic<bool> quit(false);
|
||||
static std::atomic<bool> thread(false);
|
||||
static std::mutex pcmMutex, threadMutex;
|
||||
static std::condition_variable threadCondition;
|
||||
static HINSTANCE instance;
|
||||
static HBITMAP texture = nullptr;
|
||||
static COLORREF *textureBits = nullptr;
|
||||
static HBRUSH fg = CreateSolidBrush(RGB(255, 0, 0));
|
||||
static COLORREF bg = RGB(24, 24, 24);
|
||||
|
||||
static int spectrumSize = 0;
|
||||
static float* spectrumIn = nullptr;
|
||||
static float* spectrumOut = nullptr;
|
||||
|
||||
static void renderFrame(HWND hwnd) {
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
RECT& r = ps.rcPaint;
|
||||
|
||||
{
|
||||
/* copy to the output buffer so we can write the input buffer
|
||||
immediately if we want to. */
|
||||
std::unique_lock<std::mutex> lock(pcmMutex);
|
||||
memcpy(::spectrumOut, ::spectrumIn, ::spectrumSize * sizeof(float));
|
||||
}
|
||||
|
||||
if (::spectrumOut && ::spectrumSize) {
|
||||
|
||||
win32cpp::MemoryDC memDc(hdc, ps.rcPaint);
|
||||
|
||||
for (int n = 0; n < TEXTURE_WIDTH * TEXTURE_HEIGHT - 1; n++) {
|
||||
textureBits[n] = bg;
|
||||
}
|
||||
|
||||
RECT rect;
|
||||
|
||||
int barHeight;
|
||||
const int barWidth = 7;
|
||||
const int barY = 100;
|
||||
|
||||
int x = 20;
|
||||
int n = spectrumSize / 4;
|
||||
for (int bar = 0; bar < n; bar++) {
|
||||
barHeight = 4 + (int)(spectrumOut[bar]);
|
||||
rect.left = x;
|
||||
rect.right = rect.left + barWidth;
|
||||
|
||||
int dstY = barY - barHeight;
|
||||
for (int y = barY; y > dstY; y-=2) {
|
||||
rect.top = y;
|
||||
rect.bottom = rect.top - 1;
|
||||
FillRect(memDc, &rect, fg);
|
||||
}
|
||||
|
||||
x += barWidth + 1;
|
||||
}
|
||||
}
|
||||
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK staticWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch (uMsg) {
|
||||
case WM_CLOSE: {
|
||||
DestroyWindow(hwnd);
|
||||
UnregisterClass(WINDOW_CLASS_NAME, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_DESTROY: {
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_CHAR:
|
||||
if (wParam == 0x1B) { /* esc */
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
renderFrame(hwnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void threadProc() {
|
||||
#ifdef DEBUG
|
||||
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||
_CrtSetBreakAlloc(60);
|
||||
#endif
|
||||
|
||||
// Register the windows class
|
||||
WNDCLASSW wndClass;
|
||||
wndClass.style = CS_DBLCLKS;
|
||||
wndClass.lpfnWndProc = staticWndProc;
|
||||
wndClass.cbClsExtra = 0;
|
||||
wndClass.cbWndExtra = 0;
|
||||
wndClass.hInstance = instance;
|
||||
wndClass.hIcon = NULL;
|
||||
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wndClass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
|
||||
wndClass.lpszMenuName = NULL;
|
||||
wndClass.lpszClassName = WINDOW_CLASS_NAME;
|
||||
|
||||
if (!RegisterClass(&wndClass)) {
|
||||
DWORD dwError = GetLastError();
|
||||
if (dwError != ERROR_CLASS_ALREADY_EXISTS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int windowWidth = DEFAULT_WIDTH;
|
||||
int windowHeight = DEFAULT_HEIGHT;
|
||||
|
||||
RECT rc;
|
||||
SetRect(&rc, 0, 0, windowWidth, windowHeight);
|
||||
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
|
||||
|
||||
// Create the render window
|
||||
HWND hwnd = CreateWindow(
|
||||
WINDOW_CLASS_NAME,
|
||||
L"GdiVis-musikcube",
|
||||
WS_EX_TOOLWINDOW,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
(rc.right - rc.left),
|
||||
(rc.bottom - rc.top),
|
||||
0,
|
||||
NULL,
|
||||
instance,
|
||||
0);
|
||||
|
||||
if (!hwnd) {
|
||||
DWORD dwError = GetLastError();
|
||||
return;
|
||||
}
|
||||
|
||||
BITMAPINFO bminfo;
|
||||
ZeroMemory(&bminfo, sizeof(BITMAPINFO));
|
||||
bminfo.bmiHeader.biWidth = TEXTURE_WIDTH;
|
||||
bminfo.bmiHeader.biHeight = TEXTURE_HEIGHT;
|
||||
bminfo.bmiHeader.biPlanes = 1;
|
||||
bminfo.bmiHeader.biBitCount = 32;
|
||||
bminfo.bmiHeader.biCompression = BI_RGB;
|
||||
bminfo.bmiHeader.biXPelsPerMeter = 0;
|
||||
bminfo.bmiHeader.biYPelsPerMeter = 0;
|
||||
bminfo.bmiHeader.biClrUsed = 0;
|
||||
bminfo.bmiHeader.biClrImportant = 0;
|
||||
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bminfo.bmiHeader.biSizeImage = TEXTURE_WIDTH * TEXTURE_HEIGHT * 4;
|
||||
|
||||
texture = CreateDIBSection(NULL, &bminfo, DIB_RGB_COLORS, (void **)&textureBits, NULL, NULL);
|
||||
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
|
||||
MSG msg;
|
||||
msg.message = WM_NULL;
|
||||
|
||||
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
|
||||
while (WM_QUIT != msg.message) {
|
||||
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE) != 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
else {
|
||||
if (quit) {
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
else {
|
||||
DWORD start = GetTickCount();
|
||||
InvalidateRect(hwnd, 0, false);
|
||||
UpdateWindow(hwnd);
|
||||
DWORD delta = (GetTickCount() - start);
|
||||
if (MILLIS_PER_FRAME > delta) {
|
||||
Sleep(MILLIS_PER_FRAME - delta);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeleteObject(texture);
|
||||
texture = nullptr;
|
||||
textureBits = nullptr;
|
||||
|
||||
thread.store(false);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(threadMutex);
|
||||
threadCondition.notify_all();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COMPILE_AS_EXE
|
||||
int main(int argc, char *argv[]) {
|
||||
SetProjectMDataDirectory(util::getModuleDirectory());
|
||||
|
||||
#ifndef WIN32
|
||||
std::thread background(pipeReadProc);
|
||||
background.detach();
|
||||
#endif
|
||||
|
||||
quit.store(false);
|
||||
thread.store(true);
|
||||
windowProc();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpReserved) {
|
||||
instance = hModule;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
class Visualizer : public musik::core::sdk::ISpectrumVisualizer {
|
||||
public:
|
||||
virtual const char* Name() {
|
||||
return "GdiVis";
|
||||
};
|
||||
|
||||
virtual const char* Version() {
|
||||
return "0.1.0";
|
||||
};
|
||||
|
||||
virtual const char* Author() {
|
||||
return "clangen";
|
||||
};
|
||||
|
||||
virtual void Destroy() {
|
||||
this->Hide();
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual void Write(float *spectrum, int size) {
|
||||
std::unique_lock<std::mutex> lock(pcmMutex);
|
||||
|
||||
if (::spectrumSize != size) {
|
||||
delete ::spectrumIn;
|
||||
delete ::spectrumOut;
|
||||
::spectrumSize = size;
|
||||
::spectrumIn = new float[size];
|
||||
::spectrumOut = new float[size];
|
||||
}
|
||||
|
||||
memcpy(::spectrumIn, spectrum, size * sizeof(float));
|
||||
}
|
||||
|
||||
virtual void Show() {
|
||||
if (!Visible()) {
|
||||
quit.store(false);
|
||||
thread.store(true);
|
||||
std::thread background(threadProc);
|
||||
background.detach();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Hide() {
|
||||
if (Visible()) {
|
||||
quit.store(true);
|
||||
|
||||
while (thread.load()) {
|
||||
std::unique_lock<std::mutex> lock(threadMutex);
|
||||
threadCondition.wait(lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool Visible() {
|
||||
return thread.load();
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" DLL_EXPORT musik::core::sdk::IPlugin* GetPlugin() {
|
||||
return new Visualizer();
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT musik::core::sdk::ISpectrumVisualizer* GetSpectrumVisualizer() {
|
||||
return new Visualizer();
|
||||
}
|
||||
#endif
|
103
src/contrib/win32gdivis/MemoryDC.cpp
Normal file
103
src/contrib/win32gdivis/MemoryDC.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright <20> 2007, Casey Langen
|
||||
//
|
||||
// Sources and Binaries of: win32cpp
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "MemoryDC.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace win32cpp;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MemoryDC
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///\brief
|
||||
///Constructor.
|
||||
///
|
||||
///\param hdc
|
||||
///The destination HDC. The final contents of the memory buffer will
|
||||
///be copied here upon destruction.
|
||||
///
|
||||
///\param rect
|
||||
///The Rectangle that represents the drawable area of the HDC.
|
||||
/*ctor*/ MemoryDC::MemoryDC(HDC hdc, const RECT& rect)
|
||||
: rectIsValid(false)
|
||||
, screenDC(hdc)
|
||||
, memoryBitmap(NULL)
|
||||
, memoryDC(NULL)
|
||||
, clientRect(rect)
|
||||
{
|
||||
int width = rect.right - rect.left;
|
||||
int height = rect.bottom - rect.top;
|
||||
|
||||
this->memoryDC = ::CreateCompatibleDC(this->screenDC);
|
||||
//
|
||||
this->memoryBitmap = ::CreateCompatibleBitmap(this->screenDC, width, height);
|
||||
this->oldObject = ::SelectObject(this->memoryDC, this->memoryBitmap);
|
||||
|
||||
this->rectIsValid = ((width > 0) && (height > 0));
|
||||
}
|
||||
|
||||
/*dtor*/ MemoryDC::~MemoryDC()
|
||||
{
|
||||
if (this->rectIsValid)
|
||||
{
|
||||
::BitBlt(
|
||||
this->screenDC,
|
||||
this->clientRect.left,
|
||||
this->clientRect.top,
|
||||
this->clientRect.right - this->clientRect.left,
|
||||
this->clientRect.bottom - this->clientRect.top,
|
||||
this->memoryDC,
|
||||
0,
|
||||
0,
|
||||
SRCCOPY);
|
||||
}
|
||||
|
||||
::SelectObject(this->memoryDC, this->oldObject);
|
||||
|
||||
::DeleteObject(this->memoryBitmap);
|
||||
::DeleteObject(this->memoryDC);
|
||||
}
|
||||
|
||||
///\brief
|
||||
///Returns a handle to the offscreen device context.
|
||||
MemoryDC::operator HDC()
|
||||
{
|
||||
return this->memoryDC;
|
||||
}
|
102
src/contrib/win32gdivis/MemoryDC.h
Normal file
102
src/contrib/win32gdivis/MemoryDC.h
Normal file
@ -0,0 +1,102 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright <20> 2007, Casey Langen
|
||||
//
|
||||
// Sources and Binaries of: win32cpp
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// * Neither the name of the author nor the names of other contributors may
|
||||
// be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace win32cpp {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///\brief
|
||||
///A memory device context. MemoryDC is used internally by various classes,
|
||||
///including Window, for flicker free drawing.
|
||||
///
|
||||
///When performing graphics operations on a Window's DC, changes are drawn
|
||||
///directly to screen; this leads to flickering. MemoryDC creates an offscreen
|
||||
///buffer that "accumulates" changes, which are copied to a desination DC
|
||||
///when all drawing has finished.
|
||||
///
|
||||
///MemoryDC is constructed with an HDC and a Rect as parameters, and provides
|
||||
///an implicit HDC cast operator that returns a handle to the offscreen buffer.
|
||||
///This means that regular Win32 drawing routines, such as DrawLine, FillRect,
|
||||
///etc, can transparently use a MemoryDC as if it were a regular HDC.
|
||||
///
|
||||
///When a MemoryDC's destructor is called the contents of the offscren buffer
|
||||
///are automatically copied to to the HDC it was constructed with, resulting
|
||||
///in flicker-free drawing.
|
||||
///
|
||||
///\code
|
||||
///PAINTSTRUCT paintStruct;
|
||||
///HDC hdc = ::BeginPaint(this->Handle(), &paintStruct);
|
||||
///{
|
||||
/// MemoryDC memDC(hdc, paintStruct.rcPaint);
|
||||
///
|
||||
/// //...
|
||||
/// //draw to memDC as if you were drawing to hdc
|
||||
/// //...
|
||||
///
|
||||
///} // when the MemoryDC destructor is called, the contents will be copied to hdc
|
||||
///::EndPaint(this->Handle(), &paintStruct);
|
||||
///\endcode
|
||||
///
|
||||
///\see
|
||||
///RedrawLock
|
||||
class MemoryDC
|
||||
{
|
||||
public: // constructors, destructor
|
||||
/*ctor*/ MemoryDC(HDC hdc, const RECT& rect);
|
||||
/*dtor*/ ~MemoryDC();
|
||||
|
||||
public: // operators
|
||||
operator HDC();
|
||||
|
||||
private: // instance data
|
||||
HBITMAP memoryBitmap;
|
||||
HDC memoryDC, screenDC;
|
||||
HANDLE oldObject;
|
||||
RECT clientRect;
|
||||
bool rectIsValid;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // win32cpp
|
Loading…
x
Reference in New Issue
Block a user