├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── d2dx-defaults.cfg ├── screenshots ├── d2dx1.png ├── d2dx2.png ├── d2dx3.png ├── d2dx_dxnowide1.png ├── d2dx_dxnowide2.png ├── d2dx_dxnowide3.png ├── d2dx_fxaa1.png ├── d2dx_nofxaa1.png ├── d2dx_scaling_0.png ├── d2dx_scaling_1.png ├── d2dx_scaling_2.png ├── svens1.png ├── svens2.png └── svens3.png ├── src ├── d2dx.sln ├── d2dx │ ├── Batch.h │ ├── Buffer.h │ ├── BuiltinResMod.cpp │ ├── BuiltinResMod.h │ ├── CompatibilityModeDisabler.cpp │ ├── CompatibilityModeDisabler.h │ ├── Constants.hlsli │ ├── D2DXConfigurator.cpp │ ├── D2DXConfigurator.h │ ├── D2DXContext.cpp │ ├── D2DXContext.h │ ├── D2DXContextFactory.cpp │ ├── D2DXContextFactory.h │ ├── D2Types.h │ ├── Detours.cpp │ ├── Detours.h │ ├── Display.hlsli │ ├── DisplayBilinearScalePS.hlsl │ ├── DisplayCatmullRomScalePS.hlsl │ ├── DisplayIntegerScalePS.hlsl │ ├── DisplayNonintegerScalePS.hlsl │ ├── DisplayVS.hlsl │ ├── ErrorHandling.h │ ├── FXAA.hlsli │ ├── Game.hlsli │ ├── GameHelper.cpp │ ├── GameHelper.h │ ├── GamePS.hlsl │ ├── GameVS.hlsl │ ├── GammaPS.hlsl │ ├── IBuiltinResMod.h │ ├── ID2DXContext.h │ ├── ID2InterceptionHandler.h │ ├── IGameHelper.h │ ├── IGlide3x.h │ ├── IRenderContext.h │ ├── ISimd.h │ ├── ITextureCache.h │ ├── IWin32InterceptionHandler.h │ ├── Metrics.cpp │ ├── Metrics.h │ ├── Options.cpp │ ├── Options.h │ ├── RenderContext.cpp │ ├── RenderContext.h │ ├── RenderContextResources.cpp │ ├── RenderContextResources.h │ ├── ResolveAA.hlsl │ ├── SimdSse2.cpp │ ├── SimdSse2.h │ ├── SurfaceIdTracker.cpp │ ├── SurfaceIdTracker.h │ ├── TextMotionPredictor.cpp │ ├── TextMotionPredictor.h │ ├── TextureCache.cpp │ ├── TextureCache.h │ ├── TextureCachePolicyBitPmru.cpp │ ├── TextureCachePolicyBitPmru.h │ ├── TextureHasher.cpp │ ├── TextureHasher.h │ ├── Types.h │ ├── UnitMotionPredictor.cpp │ ├── UnitMotionPredictor.h │ ├── Utils.cpp │ ├── Utils.h │ ├── Vertex.h │ ├── VideoPS.hlsl │ ├── WeatherMotionPredictor.cpp │ ├── WeatherMotionPredictor.h │ ├── d2dx.rc │ ├── d2dx.vcxproj │ ├── d2dx.vcxproj.filters │ ├── d2dx.vcxproj.user │ ├── dllmain.cpp │ ├── dx256_bmp.h │ ├── glide3x.cpp │ ├── pch.cpp │ ├── pch.h │ └── resource.h └── d2dxtests │ ├── TestBatch.cpp │ ├── TestMetrics.cpp │ ├── TestSimd.cpp │ ├── TestTextureCache.cpp │ ├── d2dxtests.vcxproj │ ├── d2dxtests.vcxproj.filters │ ├── d2dxtests.vcxproj.user │ └── pch.cpp ├── thirdparty ├── detours │ ├── detours.h │ ├── detours.lib │ ├── detours.pdb │ ├── detver.h │ ├── syelog.h │ └── syelog.lib ├── fnv │ ├── fnv.h │ ├── hash_32a.c │ └── license.txt ├── glide3 │ ├── 3DFX.H │ ├── FXDLL.H │ ├── FXGLOB.H │ ├── FXOS.H │ ├── SST1VID.H │ ├── glide.h │ ├── glidesys.h │ ├── glideutl.h │ └── sst1init.h ├── pocketlzma │ ├── pocketlzma-LICENSE.txt │ └── pocketlzma.hpp ├── sgd2freeres │ ├── SGD2FreeRes - COPYING │ ├── SGD2FreeRes - Changelog.txt │ ├── SGD2FreeRes - LICENSE.md │ ├── SGD2FreeRes - README.md │ ├── SGD2FreeRes.dll │ ├── SGD2FreeRes.dll.lzma │ ├── SGD2FreeRes.mpq │ ├── SGD2FreeRes.mpq.lzma │ └── SGD2FreeRes.pdb ├── stb_image │ └── stb_image_write.h └── toml │ ├── toml.c │ └── toml.h └── toml-LICENSE.txt /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '44 20 * * 3' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'cpp' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /src/.vs/d2dx/v16/.suo 2 | /src/.vs/ 3 | **.aps 4 | **.res 5 | **/Debug/ 6 | **/Release/ 7 | *_cso.h 8 | publish/ 9 | **_dxbc.txt 10 | /.vs/ 11 | -------------------------------------------------------------------------------- /d2dx-defaults.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # This is an example config file for D2DX. 3 | # 4 | # If you don't like the default settings, you can edit this file, rename it to "d2dx.cfg" 5 | # and place it in the game folder. 6 | # 7 | 8 | [window] 9 | scale=1 # range 1-3, an integer scale factor for the window 10 | position=[-1,-1] # if [-1,-1] the window will be centered, otherwise placed at the explicit position given here 11 | frameless=false # if true, the window frame (caption bar etc) will be removed 12 | 13 | [game] 14 | size=[-1,-1] # if [-1,-1] d2dx will decide a suitable game size, otherwise will use the size given here 15 | filtering=0 # if 0, will use high quality filtering (sharp, more pixelated) 16 | # 1, will use bilinear filtering (blurry) 17 | # 2, will use catmull-rom filtering (higher quality than bilinear) 18 | 19 | # 20 | # Opt-outs from default D2DX behavior 21 | # 22 | [optouts] 23 | noclipcursor=false # if true, will not lock the mouse cursor to the game window 24 | nofpsfix=false # if true, will not apply the basic fps fix (precludes high fps support) 25 | noresmod=false # if true, will not apply the built-in D2HD resolution mod (precludes widescreen support) 26 | nowide=false # if true, will not choose a widescreen resolution (if noresmod is true, this does nothing) 27 | nologo=false # if true, will not display the D2DX logo on the title screen 28 | novsync=false # if true, will not use vertical sync 29 | noaa=false # if true, will not apply anti-aliasing to jagged edges 30 | nocompatmodefix=false # if true, will not block the use of "Windows XP compatibility mode" 31 | notitlechange=false # if true, will not change the window title text 32 | nomotionprediction=false # if true, will not run the game graphics at high fps 33 | -------------------------------------------------------------------------------- /screenshots/d2dx1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx1.png -------------------------------------------------------------------------------- /screenshots/d2dx2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx2.png -------------------------------------------------------------------------------- /screenshots/d2dx3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx3.png -------------------------------------------------------------------------------- /screenshots/d2dx_dxnowide1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_dxnowide1.png -------------------------------------------------------------------------------- /screenshots/d2dx_dxnowide2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_dxnowide2.png -------------------------------------------------------------------------------- /screenshots/d2dx_dxnowide3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_dxnowide3.png -------------------------------------------------------------------------------- /screenshots/d2dx_fxaa1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_fxaa1.png -------------------------------------------------------------------------------- /screenshots/d2dx_nofxaa1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_nofxaa1.png -------------------------------------------------------------------------------- /screenshots/d2dx_scaling_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_scaling_0.png -------------------------------------------------------------------------------- /screenshots/d2dx_scaling_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_scaling_1.png -------------------------------------------------------------------------------- /screenshots/d2dx_scaling_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/d2dx_scaling_2.png -------------------------------------------------------------------------------- /screenshots/svens1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/svens1.png -------------------------------------------------------------------------------- /screenshots/svens2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/svens2.png -------------------------------------------------------------------------------- /screenshots/svens3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/screenshots/svens3.png -------------------------------------------------------------------------------- /src/d2dx.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30517.126 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d2dx", "d2dx\d2dx.vcxproj", "{93A28F27-8D56-470C-B699-15B0CF2C926A}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d2dxtests", "d2dxtests\d2dxtests.vcxproj", "{64214704-FE00-4DB6-BEFA-1E622F7262A1}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x86 = Debug|x86 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {93A28F27-8D56-470C-B699-15B0CF2C926A}.Debug|x86.ActiveCfg = Debug|Win32 17 | {93A28F27-8D56-470C-B699-15B0CF2C926A}.Debug|x86.Build.0 = Debug|Win32 18 | {93A28F27-8D56-470C-B699-15B0CF2C926A}.Release|x86.ActiveCfg = Release|Win32 19 | {93A28F27-8D56-470C-B699-15B0CF2C926A}.Release|x86.Build.0 = Release|Win32 20 | {64214704-FE00-4DB6-BEFA-1E622F7262A1}.Debug|x86.ActiveCfg = Debug|Win32 21 | {64214704-FE00-4DB6-BEFA-1E622F7262A1}.Debug|x86.Build.0 = Debug|Win32 22 | {64214704-FE00-4DB6-BEFA-1E622F7262A1}.Release|x86.ActiveCfg = Release|Win32 23 | {64214704-FE00-4DB6-BEFA-1E622F7262A1}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {680244CF-729A-4310-A2CA-D9ABD4923671} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/d2dx/Buffer.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ErrorHandling.h" 22 | 23 | namespace d2dx 24 | { 25 | template 26 | struct Buffer final 27 | { 28 | Buffer() noexcept : 29 | items(nullptr), 30 | capacity(0) 31 | { 32 | } 33 | 34 | Buffer(uint32_t capacity_, bool zeroFill = false) noexcept : 35 | items((T* __restrict)_aligned_malloc(sizeof(T)* capacity_, 256)), 36 | capacity(capacity_) 37 | { 38 | assert(items); 39 | 40 | if (!items) 41 | { 42 | D2DX_FATAL_ERROR("Out of memory."); 43 | } 44 | 45 | if (!zeroFill) 46 | { 47 | return; 48 | } 49 | 50 | ::memset(items, 0, sizeof(T) * capacity); 51 | } 52 | 53 | Buffer(uint32_t capacity_, bool fill, T fillValue) noexcept : 54 | Buffer(capacity_, false) 55 | { 56 | if (!fill) 57 | { 58 | return; 59 | } 60 | 61 | for (uint32_t i = 0; i < capacity; ++i) 62 | { 63 | items[i] = fillValue; 64 | } 65 | } 66 | 67 | Buffer(const Buffer&) = delete; 68 | 69 | Buffer& operator=(const Buffer&) = delete; 70 | 71 | Buffer(Buffer&& rhs) noexcept : Buffer() 72 | { 73 | std::swap(items, rhs.items); 74 | std::swap(capacity, rhs.capacity); 75 | } 76 | 77 | Buffer& operator=(Buffer&& rhs) noexcept 78 | { 79 | std::swap(items, rhs.items); 80 | std::swap(capacity, rhs.capacity); 81 | return *this; 82 | } 83 | 84 | ~Buffer() noexcept 85 | { 86 | _aligned_free(items); 87 | } 88 | 89 | T* __restrict items; 90 | uint32_t capacity; 91 | }; 92 | } 93 | -------------------------------------------------------------------------------- /src/d2dx/BuiltinResMod.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "BuiltinResMod.h" 21 | #include "Utils.h" 22 | #include "resource.h" 23 | #include "GameHelper.h" 24 | 25 | using namespace d2dx; 26 | 27 | _Use_decl_annotations_ 28 | BuiltinResMod::BuiltinResMod( 29 | HMODULE hModule, 30 | Size gameSize, 31 | const std::shared_ptr& gameHelper) 32 | { 33 | if (!hModule || !gameHelper) 34 | { 35 | D2DX_CHECK_HR(E_INVALIDARG); 36 | } 37 | 38 | _isActive = false; 39 | 40 | #ifndef D2DX_UNITTEST 41 | if (IsCompatible(gameHelper.get())) 42 | { 43 | D2DX_LOG("Writing SGD2FreeRes files."); 44 | 45 | if (!WriteResourceToFile(hModule, IDR_SGD2FR_MPQ, "mpq", "d2dx_sgd2freeres.mpq")) 46 | { 47 | D2DX_LOG("Failed to write d2dx_sgd2freeres.mpq"); 48 | } 49 | 50 | if (!WriteResourceToFile(hModule, IDR_SGD2FR_DLL, "dll", "d2dx_sgd2freeres.dll")) 51 | { 52 | D2DX_LOG("Failed to write d2dx_sgd2freeres.mpq"); 53 | } 54 | 55 | if (!WriteConfig(gameSize)) 56 | { 57 | D2DX_LOG("Failed to write SGD2FreeRes configuration."); 58 | } 59 | 60 | D2DX_LOG("Initializing SGD2FreeRes."); 61 | LoadLibraryA("d2dx_sgd2freeres.dll"); 62 | 63 | _isActive = true; 64 | return; 65 | } 66 | #endif 67 | } 68 | 69 | bool BuiltinResMod::IsActive() const 70 | { 71 | return _isActive; 72 | } 73 | 74 | _Use_decl_annotations_ 75 | bool BuiltinResMod::IsCompatible( 76 | IGameHelper* gameHelper) 77 | { 78 | auto gameVersion = gameHelper->GetVersion(); 79 | 80 | if (gameVersion != d2dx::GameVersion::Lod109d && 81 | gameVersion != d2dx::GameVersion::Lod113c && 82 | gameVersion != d2dx::GameVersion::Lod113d && 83 | gameVersion != d2dx::GameVersion::Lod114d) 84 | { 85 | D2DX_LOG("Unsupported game version, won't use built-in resolution mod."); 86 | return false; 87 | } 88 | 89 | return true; 90 | } 91 | 92 | _Use_decl_annotations_ 93 | bool BuiltinResMod::WriteResourceToFile( 94 | HMODULE hModule, 95 | int32_t resourceId, 96 | const char* ext, 97 | const char* filename) 98 | { 99 | void* payloadPtr = nullptr; 100 | DWORD payloadSize = 0; 101 | HRSRC resourceInfo = nullptr; 102 | HGLOBAL resourceData = nullptr; 103 | HANDLE file = nullptr; 104 | DWORD bytesWritten = 0; 105 | bool succeeded = true; 106 | 107 | resourceInfo = FindResourceA(hModule, MAKEINTRESOURCEA(resourceId), ext); 108 | if (!resourceInfo) 109 | { 110 | succeeded = false; 111 | goto end; 112 | } 113 | 114 | resourceData = LoadResource(hModule, resourceInfo); 115 | if (!resourceData) 116 | { 117 | succeeded = false; 118 | goto end; 119 | } 120 | 121 | payloadSize = SizeofResource(hModule, resourceInfo); 122 | payloadPtr = LockResource(resourceData); 123 | if (!payloadPtr || !payloadSize) 124 | { 125 | succeeded = false; 126 | goto end; 127 | } 128 | 129 | succeeded = DecompressLZMAToFile((const uint8_t*)payloadPtr, payloadSize, filename); 130 | 131 | end: 132 | if (resourceData) 133 | { 134 | UnlockResource(resourceData); 135 | } 136 | if (file) 137 | { 138 | CloseHandle(file); 139 | } 140 | 141 | return succeeded; 142 | } 143 | 144 | _Use_decl_annotations_ 145 | bool BuiltinResMod::WriteConfig( 146 | _In_ Size gameSize) 147 | { 148 | HANDLE file = nullptr; 149 | DWORD bytesWritten = 0; 150 | bool succeeded = true; 151 | 152 | file = CreateFileA("d2dx_sgd2freeres.json", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 153 | if (!file) 154 | { 155 | succeeded = false; 156 | goto end; 157 | } 158 | 159 | char configStr[1024]; 160 | 161 | sprintf_s(configStr, 162 | "{\r\n" 163 | " \"D2DX\" : \"PLEASE DO NOT EDIT THIS CONFIGURATION FILE. IT IS GENERATED ON EVERY STARTUP.\",\r\n" 164 | " \"SlashGaming Diablo II Free Resolution\": {\r\n" 165 | " \"!!!Metadata (Do not modify)!!!\": {\r\n" 166 | " \"Major Version A\": 3,\r\n" 167 | " \"Major Version B\" : 0,\r\n" 168 | " \"Minor Version A\" : 1,\r\n" 169 | " \"Minor Version B\" : 0\r\n" 170 | " },\r\n" 171 | " \"Ingame Resolutions\": [\r\n" 172 | " \"640x480\",\r\n" 173 | " \"800x600\",\r\n" 174 | " \"%ix%i\"\r\n" 175 | " ],\r\n" 176 | " \"Ingame Resolution Mode\" : 2,\r\n" 177 | " \"Main Menu Resolution\" : \"800x600\",\r\n" 178 | " \"Custom MPQ File\": \"d2dx_sgd2freeres.mpq\",\r\n" 179 | " \"Enable Screen Border Frame?\" : true,\r\n" 180 | " \"Use Original Screen Border Frame?\" : false,\r\n" 181 | " \"Use 800 Interface Bar?\" : true\r\n" 182 | " },\r\n" 183 | " \"!!!Globals!!!\": {\r\n" 184 | " \"Config Tab Width\": 4\r\n" 185 | " }\r\n" 186 | "}\r\n", 187 | gameSize.width, gameSize.height); 188 | 189 | if (!WriteFile(file, configStr, strlen(configStr), &bytesWritten, nullptr)) 190 | { 191 | succeeded = false; 192 | goto end; 193 | } 194 | 195 | end: 196 | if (file) 197 | { 198 | CloseHandle(file); 199 | } 200 | 201 | return succeeded; 202 | } 203 | -------------------------------------------------------------------------------- /src/d2dx/BuiltinResMod.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IBuiltinResMod.h" 22 | #include "IGameHelper.h" 23 | 24 | namespace d2dx 25 | { 26 | class BuiltinResMod final : public IBuiltinResMod 27 | { 28 | public: 29 | BuiltinResMod( 30 | _In_ HMODULE hModule, 31 | _In_ Size gameSize, 32 | _In_ const std::shared_ptr& gameHelper); 33 | 34 | virtual ~BuiltinResMod() noexcept {} 35 | 36 | virtual bool IsActive() const override; 37 | 38 | private: 39 | bool IsCompatible( 40 | _In_ IGameHelper* gameHelper); 41 | 42 | bool WriteResourceToFile( 43 | _In_ HMODULE hModule, 44 | _In_ int32_t resourceId, 45 | _In_z_ const char* ext, 46 | _In_z_ const char* filename); 47 | 48 | bool WriteConfig( 49 | _In_ Size gameSize); 50 | 51 | bool _isActive = false; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /src/d2dx/CompatibilityModeDisabler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "CompatibilityModeDisabler.h" 21 | #include "Utils.h" 22 | 23 | using namespace d2dx; 24 | 25 | static const wchar_t* osCompatibilityOptions[] = 26 | { 27 | L"WIN95", 28 | L"WIN98", 29 | L"WINXP", 30 | L"VISTA", 31 | L"WIN7", 32 | L"WIN8" 33 | }; 34 | 35 | CompatibilityModeDisabler::CompatibilityModeDisabler() 36 | { 37 | } 38 | 39 | void CompatibilityModeDisabler::DisableCompatibilityMode() 40 | { 41 | bool fixedCompatibilityMode = false; 42 | 43 | if (FixCompatibilityMode(HKEY_CURRENT_USER, L"Game.exe")) 44 | { 45 | fixedCompatibilityMode = true; 46 | } 47 | 48 | if (FixCompatibilityMode(HKEY_CURRENT_USER, L"Diablo II.exe")) 49 | { 50 | fixedCompatibilityMode = true; 51 | } 52 | 53 | if (fixedCompatibilityMode) 54 | { 55 | MessageBox(NULL, L"D2DX detected that 'compatibility mode' (e.g. for Windows XP) was set for the game, but this isn't necessary for D2DX and will cause problems.\n\nThis has now been fixed for you. Please re-launch the game.", L"D2DX", MB_OK); 56 | TerminateProcess(GetCurrentProcess(), -1); 57 | } 58 | 59 | // If compat mode is set for LOCAL_MACHINE, we can't see it in the registry and can't fix that... so try to detect it at least. 60 | 61 | // Get the reported (false) OS version. 62 | auto reportedWindowsVersion = d2dx::GetWindowsVersion(); 63 | auto realWindowsVersion = d2dx::GetActualWindowsVersion(); 64 | 65 | if (reportedWindowsVersion.major != realWindowsVersion.major) 66 | { 67 | MessageBox(NULL, L"D2DX detected that 'compatibility mode' (e.g. for Windows XP) was set for the game, but this isn't necessary for D2DX and will cause problems.\n\nPlease disable 'compatibility mode' for both 'Game.exe' and 'Diablo II.exe'.", L"D2DX", MB_OK); 68 | TerminateProcess(GetCurrentProcess(), -1); 69 | } 70 | 71 | if (reportedWindowsVersion.major < 6 || (reportedWindowsVersion.major == 6 && reportedWindowsVersion.minor == 0)) 72 | { 73 | MessageBox(NULL, L"D2DX requires Windows 7 or above.", L"D2DX", MB_OK); 74 | TerminateProcess(GetCurrentProcess(), -1); 75 | } 76 | } 77 | 78 | _Use_decl_annotations_ 79 | bool CompatibilityModeDisabler::FixCompatibilityMode( 80 | _In_ HKEY hRootKey, 81 | _In_z_ const wchar_t* filename) 82 | { 83 | HKEY hKey; 84 | LPCTSTR compatibilityLayersKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"; 85 | LONG result = RegOpenKeyEx(hRootKey, compatibilityLayersKey, 0, KEY_READ | KEY_WRITE, &hKey); 86 | if (result != ERROR_SUCCESS) 87 | { 88 | return false; 89 | } 90 | 91 | Buffer fullPath(2048); 92 | uint32_t numChars = GetModuleFileName(GetModuleHandle(nullptr), fullPath.items, fullPath.capacity); 93 | if (numChars < 1 || numChars >= fullPath.capacity) 94 | { 95 | RegCloseKey(hKey); 96 | return false; 97 | } 98 | 99 | bool hasFixed = false; 100 | 101 | Buffer value(2048); 102 | uint32_t type = REG_SZ; 103 | uint32_t size = value.capacity; 104 | 105 | result = RegGetValue(hKey, nullptr, fullPath.items, RRF_RT_REG_SZ, (LPDWORD)&type, nullptr, (LPDWORD)&size); 106 | 107 | if (result == ERROR_SUCCESS) 108 | { 109 | if (size > value.capacity) 110 | { 111 | RegCloseKey(hKey); 112 | return false; 113 | } 114 | 115 | result = RegGetValue(hKey, nullptr, fullPath.items, RRF_RT_REG_SZ, (LPDWORD)&type, (LPBYTE)value.items, (LPDWORD)&size); 116 | 117 | if (result == ERROR_SUCCESS) 118 | { 119 | if (HasOsCompatibilityOption(value.items)) 120 | { 121 | result = RegDeleteValue(hKey, fullPath.items); 122 | assert(result == ERROR_SUCCESS); 123 | 124 | RegCloseKey(hKey); 125 | return true; 126 | } 127 | } 128 | } 129 | 130 | RegCloseKey(hKey); 131 | return false; 132 | } 133 | 134 | _Use_decl_annotations_ 135 | bool CompatibilityModeDisabler::HasOsCompatibilityOption( 136 | const wchar_t* options) 137 | { 138 | for (int32_t i = 0; i < ARRAYSIZE(osCompatibilityOptions); ++i) 139 | { 140 | if (wcsstr(options, osCompatibilityOptions[i])) 141 | { 142 | return true; 143 | } 144 | } 145 | 146 | return false; 147 | } 148 | -------------------------------------------------------------------------------- /src/d2dx/CompatibilityModeDisabler.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | namespace d2dx 22 | { 23 | class CompatibilityModeDisabler final 24 | { 25 | public: 26 | CompatibilityModeDisabler(); 27 | 28 | ~CompatibilityModeDisabler() noexcept {} 29 | 30 | void DisableCompatibilityMode(); 31 | 32 | private: 33 | bool FixCompatibilityMode( 34 | _In_ HKEY hRootKey, 35 | _In_z_ const wchar_t* filename); 36 | 37 | bool HasOsCompatibilityOption( 38 | _In_z_ const wchar_t* options); 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /src/d2dx/Constants.hlsli: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | 20 | cbuffer Constants : register(b0) 21 | { 22 | float2 c_screenSize : packoffset(c0); 23 | float2 c_invScreenSize : packoffset(c0.z); 24 | uint4 flagsx : packoffset(c1); 25 | }; 26 | 27 | SamplerState PointSampler : register(s0); 28 | SamplerState BilinearSampler : register(s1); 29 | 30 | #define FLAGS_CHROMAKEY_ENABLED_MASK 1 31 | -------------------------------------------------------------------------------- /src/d2dx/D2DXConfigurator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "D2DXContextFactory.h" 21 | #include "D2DXConfigurator.h" 22 | 23 | using namespace d2dx; 24 | using namespace std; 25 | using namespace Microsoft::WRL; 26 | 27 | class D2DXConfigurator : public ID2DXConfigurator 28 | { 29 | public: 30 | D2DXConfigurator() noexcept 31 | { 32 | } 33 | 34 | virtual ~D2DXConfigurator() noexcept 35 | { 36 | } 37 | 38 | STDMETHOD(QueryInterface)( 39 | /* [in] */ REFIID riid, 40 | /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) 41 | { 42 | if (IsEqualIID(riid, __uuidof(IUnknown)) || 43 | IsEqualIID(riid, __uuidof(ID2DXConfigurator))) 44 | { 45 | *ppvObject = this; 46 | return S_OK; 47 | } 48 | else 49 | { 50 | *ppvObject = nullptr; 51 | return E_NOINTERFACE; 52 | } 53 | } 54 | 55 | STDMETHOD_(ULONG, AddRef)(void) 56 | { 57 | /* We just pretend to be refcounted. */ 58 | return 1U; 59 | } 60 | 61 | STDMETHOD_(ULONG, Release)(void) 62 | { 63 | /* We just pretend to be refcounted. */ 64 | return 1U; 65 | } 66 | 67 | STDMETHOD(SetCustomResolution)( 68 | int32_t width, 69 | int32_t height) noexcept 70 | { 71 | auto d2dxContext = D2DXContextFactory::GetInstance(false); 72 | 73 | if (!d2dxContext) 74 | { 75 | return E_POINTER; 76 | } 77 | 78 | d2dxContext->SetCustomResolution({ width, height }); 79 | 80 | return S_OK; 81 | } 82 | 83 | STDMETHOD(GetSuggestedCustomResolution)( 84 | _Out_ int32_t* width, 85 | _Out_ int32_t* height) noexcept 86 | { 87 | if (!width || !height) 88 | { 89 | return E_INVALIDARG; 90 | } 91 | 92 | auto d2dxContext = D2DXContextFactory::GetInstance(false); 93 | 94 | if (!d2dxContext) 95 | { 96 | return E_POINTER; 97 | } 98 | 99 | Size size = d2dxContext->GetSuggestedCustomResolution(); 100 | *width = size.width; 101 | *height = size.height; 102 | 103 | return S_OK; 104 | } 105 | }; 106 | 107 | namespace d2dx 108 | { 109 | ID2DXConfigurator* GetConfiguratorInternal() 110 | { 111 | static D2DXConfigurator configurator; 112 | return &configurator; 113 | } 114 | } 115 | 116 | extern "C" 117 | { 118 | D2DX_EXPORTED ID2DXConfigurator* __stdcall D2DXGetConfigurator() 119 | { 120 | auto d2dxInstance = D2DXContextFactory::GetInstance(false); 121 | 122 | if (!d2dxInstance) 123 | { 124 | return nullptr; 125 | } 126 | 127 | d2dxInstance->DisableBuiltinResMod(); 128 | 129 | return GetConfiguratorInternal(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/d2dx/D2DXConfigurator.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | #include 21 | #include 22 | 23 | #ifdef D2DX_EXPORT 24 | #define D2DX_EXPORTED __declspec(dllexport) 25 | #else 26 | #define D2DX_EXPORTED 27 | #endif 28 | 29 | /* 30 | ID2DXConfigurator is a pseudo-COM interface that can be used to integrate with D2DX. 31 | It is suitable e.g. for "high-res" mods that want to use arbitrary resolutions. 32 | 33 | It can be accessed via the helper d2dx::TryGetConfigurator, or manually by 34 | using LoadLibrary/GetProcAddress to get a pointer to _D2DXGetConfigurator@4. 35 | 36 | Note that the object is not really refcounted and there's no need to call AddRef/Release. 37 | 38 | Note also that the built-in resolution mod in D2DX will be disabled if D2DXGetConfigurator 39 | is called prior to the first Glide call made. 40 | 41 | Example use: 42 | 43 | ID2DXConfigurator* d2dxConfigurator = d2dx::TryGetConfigurator(); 44 | if (d2dxConfigurator) 45 | { 46 | d2dxConfigurator->SetCustomResolution(1000, 500); 47 | } 48 | grSstWinOpen(hWnd, ...) 49 | 50 | */ 51 | MIDL_INTERFACE("B11C5FA4-983F-4E34-9E43-BD82F9CCDB65") 52 | ID2DXConfigurator : public IUnknown 53 | { 54 | public: 55 | /* 56 | Tell D2DX that the following call(s) to grSstWinOpen intends this custom resolution, 57 | and to ignore the 'screen_resolution' argument. To return to normal behavior, call 58 | this method with a width and height of zero. 59 | 60 | Returns S_OK on success and an HRESULT error code otherwise. 61 | */ 62 | virtual HRESULT STDMETHODCALLTYPE SetCustomResolution( 63 | int width, 64 | int height) = 0; 65 | 66 | /* 67 | Get a suggested custom resolution from D2DX (typically close to 640x480 or 800x600, 68 | but in the aspect ratio of the monitor). 69 | 70 | This method allows matching D2DX's default behavior. 71 | 72 | Returns S_OK on success and an HRESULT error code otherwise. 73 | */ 74 | virtual HRESULT STDMETHODCALLTYPE GetSuggestedCustomResolution( 75 | /* [out] */ int* width, 76 | /* [out] */ int* height) = 0; 77 | }; 78 | 79 | extern "C" 80 | { 81 | D2DX_EXPORTED ID2DXConfigurator* __stdcall D2DXGetConfigurator(); 82 | } 83 | 84 | #if __cplusplus > 199711L 85 | namespace d2dx 86 | { 87 | namespace detail 88 | { 89 | class D2DXGetConfiguratorFuncLoader final 90 | { 91 | public: 92 | D2DXGetConfiguratorFuncLoader() : _d2dxGetConfiguratorFunc{ nullptr } 93 | { 94 | HINSTANCE hD2DX = LoadLibraryA("glide3x.dll"); 95 | if (hD2DX) 96 | { 97 | _d2dxGetConfiguratorFunc = (D2DXGetConfiguratorFunc)GetProcAddress( 98 | hD2DX, "_D2DXGetConfigurator@4"); 99 | } 100 | } 101 | ID2DXConfigurator* operator()() 102 | { 103 | return _d2dxGetConfiguratorFunc ? _d2dxGetConfiguratorFunc() : nullptr; 104 | } 105 | private: 106 | typedef ID2DXConfigurator* (__stdcall *D2DXGetConfiguratorFunc)(); 107 | D2DXGetConfiguratorFunc _d2dxGetConfiguratorFunc; 108 | }; 109 | } 110 | static ID2DXConfigurator* TryGetConfigurator() 111 | { 112 | static detail::D2DXGetConfiguratorFuncLoader d2dxGetConfiguratorFuncLoader; 113 | return d2dxGetConfiguratorFuncLoader(); 114 | } 115 | } 116 | #endif 117 | -------------------------------------------------------------------------------- /src/d2dx/D2DXContext.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/src/d2dx/D2DXContext.cpp -------------------------------------------------------------------------------- /src/d2dx/D2DXContextFactory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "D2DXContextFactory.h" 21 | #include "GameHelper.h" 22 | #include "SimdSse2.h" 23 | #include "D2DXContext.h" 24 | #include "CompatibilityModeDisabler.h" 25 | 26 | using namespace d2dx; 27 | 28 | static bool destroyed = false; 29 | static std::shared_ptr instance; 30 | 31 | ID2DXContext* D2DXContextFactory::GetInstance( 32 | bool createIfNeeded) 33 | { 34 | /* The game is single threaded and there's no worry about synchronization. */ 35 | 36 | if (!instance && !destroyed && createIfNeeded) 37 | { 38 | auto gameHelper = std::make_shared(); 39 | auto simd = std::make_shared(); 40 | auto compatibilityModeDisabler = std::make_shared(); 41 | instance = std::make_shared(gameHelper, simd, compatibilityModeDisabler); 42 | } 43 | 44 | return instance.get(); 45 | } 46 | 47 | void D2DXContextFactory::DestroyInstance() 48 | { 49 | instance = nullptr; 50 | destroyed = true; 51 | } 52 | -------------------------------------------------------------------------------- /src/d2dx/D2DXContextFactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ID2DXContext.h" 22 | 23 | namespace d2dx 24 | { 25 | class D2DXContextFactory 26 | { 27 | public: 28 | static ID2DXContext* GetInstance(bool createIfNeeded = true); 29 | static void DestroyInstance(); 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /src/d2dx/Detours.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | namespace d2dx 22 | { 23 | struct IGameHelper; 24 | struct ID2DXContext; 25 | 26 | void AttachDetours(); 27 | 28 | void AttachLateDetours( 29 | _In_ IGameHelper* gameHelper, 30 | _In_ ID2DXContext* d2dxContext); 31 | 32 | void DetachLateDetours(); 33 | 34 | void DetachDetours(); 35 | } 36 | -------------------------------------------------------------------------------- /src/d2dx/Display.hlsli: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | 20 | struct DisplayVSInput 21 | { 22 | int2 pos : POSITION; 23 | int2 st : TEXCOORD0; 24 | float4 color : COLOR; 25 | uint2 misc : TEXCOORD1; 26 | }; 27 | 28 | struct DisplayVSOutput 29 | { 30 | noperspective float2 tc : TEXCOORD0; 31 | nointerpolation float4 textureSize_invTextureSize : TEXCOORD1; 32 | }; 33 | 34 | typedef DisplayVSOutput DisplayPSInput; 35 | -------------------------------------------------------------------------------- /src/d2dx/DisplayBilinearScalePS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | Texture2D sceneTexture : register(t0); 23 | 24 | float4 main( 25 | in DisplayPSInput ps_in) : SV_TARGET 26 | { 27 | return sceneTexture.Sample(BilinearSampler, ps_in.tc); 28 | } 29 | -------------------------------------------------------------------------------- /src/d2dx/DisplayCatmullRomScalePS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | Texture2D sceneTexture : register(t0); 23 | 24 | // This filtering code under MIT license, taken from: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1 25 | 26 | // Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16. 27 | // See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details 28 | float4 SampleTextureCatmullRom(in Texture2D tex, in SamplerState linearSampler, in float2 uv, in float4 texSize_invTexSize) 29 | { 30 | // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding 31 | // down the sample location to get the exact center of our "starting" texel. The starting texel will be at 32 | // location [1, 1] in the grid, where [0, 0] is the top left corner. 33 | float2 samplePos = uv * texSize_invTexSize.xy; 34 | float2 texPos1 = floor(samplePos - 0.5f) + 0.5f; 35 | 36 | // Compute the fractional offset from our starting texel to our original sample location, which we'll 37 | // feed into the Catmull-Rom spline function to get our filter weights. 38 | float2 f = samplePos - texPos1; 39 | 40 | // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier. 41 | // These equations are pre-expanded based on our knowledge of where the texels will be located, 42 | // which lets us avoid having to evaluate a piece-wise function. 43 | float2 w0 = f * (-0.5f + f * (1.0f - 0.5f * f)); 44 | float2 w1 = 1.0f + f * f * (-2.5f + 1.5f * f); 45 | float2 w2 = f * (0.5f + f * (2.0f - 1.5f * f)); 46 | float2 w3 = f * f * (-0.5f + 0.5f * f); 47 | 48 | // Work out weighting factors and sampling offsets that will let us use bilinear filtering to 49 | // simultaneously evaluate the middle 2 samples from the 4x4 grid. 50 | float2 w12 = w1 + w2; 51 | float2 offset12 = w2 / (w1 + w2); 52 | 53 | // Compute the final UV coordinates we'll use for sampling the texture 54 | float2 texPos0 = texPos1 - 1; 55 | float2 texPos3 = texPos1 + 2; 56 | float2 texPos12 = texPos1 + offset12; 57 | 58 | texPos0 *= texSize_invTexSize.zw; 59 | texPos3 *= texSize_invTexSize.zw; 60 | texPos12 *= texSize_invTexSize.zw; 61 | 62 | float3 result = 63 | (tex.SampleLevel(linearSampler, float2(texPos0.x, texPos0.y), 0.0f).rgb * w0.x + 64 | tex.SampleLevel(linearSampler, float2(texPos12.x, texPos0.y), 0.0f).rgb * w12.x + 65 | tex.SampleLevel(linearSampler, float2(texPos3.x, texPos0.y), 0.0f).rgb * w3.x) * w0.y; 66 | 67 | result += 68 | (tex.SampleLevel(linearSampler, float2(texPos0.x, texPos12.y), 0.0f).rgb * w0.x + 69 | tex.SampleLevel(linearSampler, float2(texPos12.x, texPos12.y), 0.0f).rgb * w12.x + 70 | tex.SampleLevel(linearSampler, float2(texPos3.x, texPos12.y), 0.0f).rgb * w3.x) * w12.y; 71 | 72 | result += 73 | (tex.SampleLevel(linearSampler, float2(texPos0.x, texPos3.y), 0.0f).rgb * w0.x + 74 | tex.SampleLevel(linearSampler, float2(texPos12.x, texPos3.y), 0.0f).rgb * w12.x + 75 | tex.SampleLevel(linearSampler, float2(texPos3.x, texPos3.y), 0.0f).rgb * w3.x) * w3.y; 76 | 77 | return float4(result, 1); 78 | } 79 | 80 | float4 main( 81 | in DisplayPSInput ps_in) : SV_TARGET 82 | { 83 | return SampleTextureCatmullRom(sceneTexture, BilinearSampler, ps_in.tc, ps_in.textureSize_invTextureSize); 84 | } 85 | -------------------------------------------------------------------------------- /src/d2dx/DisplayIntegerScalePS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | Texture2D sceneTexture : register(t0); 23 | 24 | float4 main( 25 | in DisplayPSInput ps_in) : SV_TARGET 26 | { 27 | return sceneTexture.SampleLevel(PointSampler, ps_in.tc, 0); 28 | } 29 | -------------------------------------------------------------------------------- /src/d2dx/DisplayNonintegerScalePS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | Texture2D sceneTexture : register(t0); 23 | 24 | /* Anti-aliased nearest-neighbor sampling, taken from https://www.shadertoy.com/view/WtjyWy by user Amarcoli. */ 25 | float2 nearestSampleUV_AA(float2 uv, float sharpness, float4 textureSize_invTextureSize) { 26 | float2 tileUv = uv * textureSize_invTextureSize.xy; 27 | float2 dxdy = float2(ddx(tileUv.x), ddy(tileUv.y)); 28 | 29 | float2 texelDelta = frac(tileUv) - 0.5; 30 | float2 distFromEdge = 0.5 - abs(texelDelta); 31 | float2 aa_factor = saturate(distFromEdge * sharpness / dxdy); 32 | 33 | return uv - texelDelta * aa_factor * textureSize_invTextureSize.zw; 34 | } 35 | 36 | float4 main( 37 | in DisplayPSInput ps_in) : SV_TARGET 38 | { 39 | return sceneTexture.Sample(BilinearSampler, nearestSampleUV_AA(ps_in.tc, 2.0, ps_in.textureSize_invTextureSize)); 40 | } 41 | -------------------------------------------------------------------------------- /src/d2dx/DisplayVS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | void main( 23 | in DisplayVSInput vs_in, 24 | uint vs_in_vertexId : SV_VertexID, 25 | out DisplayVSOutput vs_out, 26 | out noperspective float4 vs_out_pos : SV_POSITION) 27 | { 28 | float2 fpos = float2(vs_in.pos) * c_invScreenSize - 0.5; 29 | vs_out_pos = fpos.xyxx * float4(2, -2, 0, 0) + float4(0,0,0,1); 30 | 31 | float2 stf = vs_in.st; 32 | vs_out.textureSize_invTextureSize = float4(stf, 1/stf); 33 | 34 | const float srcWidth = vs_in.misc.y & 16383; 35 | const float srcHeight = vs_in.misc.x & 4095; 36 | 37 | switch (vs_in_vertexId) 38 | { 39 | default: 40 | case 0: 41 | vs_out.tc = float2(0, 0); 42 | break; 43 | case 1: 44 | vs_out.tc = float2(srcWidth * 2 * vs_out.textureSize_invTextureSize.z, 0); 45 | break; 46 | case 2: 47 | vs_out.tc = float2(0, srcHeight * 2 * vs_out.textureSize_invTextureSize.w); 48 | break; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/d2dx/ErrorHandling.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | namespace d2dx 22 | { 23 | namespace detail 24 | { 25 | __declspec(noinline) void ThrowFromHRESULT(HRESULT hr, _In_z_ const char* func, int32_t line); 26 | __declspec(noinline) char* GetMessageForHRESULT(HRESULT hr, _In_z_ const char* func, int32_t line) noexcept; 27 | [[noreturn]] __declspec(noinline) void FatalException() noexcept; 28 | [[noreturn]] __declspec(noinline) void FatalError(_In_z_ const char* msg) noexcept; 29 | } 30 | 31 | struct ComException final : public std::runtime_error 32 | { 33 | ComException(HRESULT hr_, const char* func_, int32_t line_) : 34 | std::runtime_error(detail::GetMessageForHRESULT(hr, func_, line_)), 35 | hr{ hr_ }, 36 | func{ func_ }, 37 | line{ line_ } 38 | { 39 | } 40 | 41 | HRESULT hr; 42 | const char* func; 43 | int32_t line; 44 | }; 45 | 46 | #define D2DX_THROW_HR(hr) detail::ThrowFromHRESULT(hr, __FUNCTION__, __LINE__) 47 | #define D2DX_CHECK_HR(expr) { HRESULT hr = (expr); if (FAILED(hr)) { detail::ThrowFromHRESULT((hr), __FUNCTION__, __LINE__); } } 48 | #define D2DX_FATAL_EXCEPTION detail::FatalException() 49 | #define D2DX_FATAL_ERROR(msg) detail::FatalError(msg) 50 | } 51 | -------------------------------------------------------------------------------- /src/d2dx/Game.hlsli: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | 20 | struct GameVSInput 21 | { 22 | int2 pos : POSITION; 23 | int2 texCoord : TEXCOORD0; 24 | float4 color : COLOR0; 25 | uint2 misc : TEXCOORD1; 26 | }; 27 | 28 | struct GameVSOutput 29 | { 30 | noperspective float4 pos : SV_POSITION; 31 | noperspective float2 tc : TEXCOORD0; 32 | noperspective float4 color : COLOR0; 33 | nointerpolation uint4 atlasIndex_paletteIndex_surfaceId_flags : TEXCOORD1; 34 | }; 35 | 36 | typedef GameVSOutput GamePSInput; 37 | 38 | struct GamePSOutput 39 | { 40 | float4 color : SV_TARGET0; 41 | float surfaceId : SV_TARGET1; 42 | }; 43 | -------------------------------------------------------------------------------- /src/d2dx/GameHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IGameHelper.h" 22 | #include "Types.h" 23 | 24 | namespace d2dx 25 | { 26 | class GameHelper final : public IGameHelper 27 | { 28 | public: 29 | GameHelper(); 30 | virtual ~GameHelper() noexcept {} 31 | 32 | virtual GameVersion GetVersion() const override; 33 | 34 | virtual _Ret_z_ const char* GetVersionString() const override; 35 | 36 | virtual uint32_t ScreenOpenMode() const override; 37 | 38 | virtual Size GetConfiguredGameSize() const override; 39 | 40 | virtual GameAddress IdentifyGameAddress( 41 | _In_ uint32_t returnAddress) const override; 42 | 43 | virtual TextureCategory GetTextureCategoryFromHash( 44 | _In_ uint32_t textureHash) const override; 45 | 46 | virtual TextureCategory RefineTextureCategoryFromGameAddress( 47 | _In_ TextureCategory previousCategory, 48 | _In_ GameAddress gameAddress) const override; 49 | 50 | virtual bool TryApplyInGameFpsFix() override; 51 | 52 | virtual bool TryApplyMenuFpsFix() override; 53 | 54 | virtual bool TryApplyInGameSleepFixes() override; 55 | 56 | virtual void* GetFunction( 57 | _In_ D2Function function) const override; 58 | 59 | virtual DrawParameters GetDrawParameters( 60 | _In_ const D2::CellContext* cellContext) const override; 61 | 62 | virtual D2::UnitAny* GetPlayerUnit() const override; 63 | 64 | virtual Offset GetUnitPos( 65 | _In_ const D2::UnitAny* unit) const override; 66 | 67 | virtual D2::UnitType GetUnitType( 68 | _In_ const D2::UnitAny* unit) const override; 69 | 70 | virtual uint32_t GetUnitId( 71 | _In_ const D2::UnitAny* unit) const override; 72 | 73 | virtual D2::UnitAny* FindUnit( 74 | _In_ uint32_t unitId, 75 | _In_ D2::UnitType unitType) const override; 76 | 77 | virtual int32_t GetCurrentAct() const override; 78 | 79 | virtual bool IsGameMenuOpen() const override; 80 | 81 | virtual bool IsInGame() const override; 82 | 83 | virtual bool IsProjectDiablo2() const override; 84 | 85 | private: 86 | GameVersion GetGameVersion(); 87 | 88 | void InitializeTextureHashPrefixTable(); 89 | 90 | bool ProbeUInt32( 91 | _In_ HANDLE hModule, 92 | _In_ uint32_t offset, 93 | _In_ uint32_t expectedValue); 94 | 95 | void PatchUInt32( 96 | _In_ HANDLE hModule, 97 | _In_ uint32_t offset, 98 | _In_ uint32_t value); 99 | 100 | HANDLE _hProcess; 101 | HANDLE _hGameExe; 102 | HANDLE _hD2ClientDll; 103 | HANDLE _hD2CommonDll; 104 | HANDLE _hD2GfxDll; 105 | HANDLE _hD2WinDll; 106 | GameVersion _version; 107 | bool _isProjectDiablo2; 108 | }; 109 | } 110 | -------------------------------------------------------------------------------- /src/d2dx/GamePS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Game.hlsli" 21 | 22 | Texture2DArray tex : register(t0); 23 | Texture1DArray palette : register(t1); 24 | 25 | void main( 26 | in GamePSInput ps_in, 27 | out GamePSOutput ps_out) 28 | { 29 | const uint atlasIndex = ps_in.atlasIndex_paletteIndex_surfaceId_flags.x; 30 | const bool chromaKeyEnabled = ps_in.atlasIndex_paletteIndex_surfaceId_flags.w & 1; 31 | const uint surfaceId = ps_in.atlasIndex_paletteIndex_surfaceId_flags.z; 32 | const uint paletteIndex = ps_in.atlasIndex_paletteIndex_surfaceId_flags.y; 33 | 34 | const uint indexedColor = tex.Load(int4(ps_in.tc, atlasIndex, 0)); 35 | 36 | if (chromaKeyEnabled && indexedColor == 0) 37 | discard; 38 | 39 | const float4 textureColor = palette.Load(int3(indexedColor, paletteIndex, 0)); 40 | 41 | ps_out.color = ps_in.color * textureColor; 42 | ps_out.surfaceId = ps_in.color.a > 0.5 ? surfaceId * 1.0 / 16383.0 : 0.0; 43 | } 44 | -------------------------------------------------------------------------------- /src/d2dx/GameVS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Game.hlsli" 21 | 22 | void main( 23 | in GameVSInput vs_in, 24 | out GameVSOutput vs_out) 25 | { 26 | float2 unitPos = float2(vs_in.pos) * c_invScreenSize - 0.5; 27 | vs_out.pos = unitPos.xyxx * float4(2, -2, 0, 0) + float4(0, 0, 0, 1); 28 | vs_out.tc = vs_in.texCoord; 29 | vs_out.color = vs_in.color; 30 | vs_out.atlasIndex_paletteIndex_surfaceId_flags.x = vs_in.misc.x & 4095; 31 | vs_out.atlasIndex_paletteIndex_surfaceId_flags.y = (vs_in.misc.x >> 12) | ((vs_in.misc.y & 0x8000) ? 0x10 : 0); 32 | vs_out.atlasIndex_paletteIndex_surfaceId_flags.z = vs_in.misc.y & 16383; 33 | vs_out.atlasIndex_paletteIndex_surfaceId_flags.w = (vs_in.misc.y & 0x4000) ? 1 : 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/d2dx/GammaPS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | Texture2D sceneTexture : register(t0); 23 | Texture1D gammaTexture : register(t1); 24 | 25 | float4 main( 26 | in DisplayPSInput ps_in) : SV_TARGET 27 | { 28 | float4 c = sceneTexture.SampleLevel(PointSampler, ps_in.tc, 0); 29 | c.r = gammaTexture.SampleLevel(BilinearSampler, c.r, 0).r; 30 | c.g = gammaTexture.SampleLevel(BilinearSampler, c.g, 0).g; 31 | c.b = gammaTexture.SampleLevel(BilinearSampler, c.b, 0).b; 32 | c.a = dot(c.rgb, float3(0.299, 0.587, 0.114)); 33 | return c; 34 | } 35 | -------------------------------------------------------------------------------- /src/d2dx/IBuiltinResMod.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Types.h" 22 | 23 | namespace d2dx 24 | { 25 | struct IBuiltinResMod abstract 26 | { 27 | virtual ~IBuiltinResMod() noexcept {} 28 | 29 | virtual bool IsActive() const = 0; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /src/d2dx/ID2DXContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IGlide3x.h" 22 | #include "IWin32InterceptionHandler.h" 23 | #include "ID2InterceptionHandler.h" 24 | #include "Options.h" 25 | 26 | namespace d2dx 27 | { 28 | enum class Feature 29 | { 30 | UnitMotionPrediction = 1, 31 | WeatherMotionPrediction = 2, 32 | TextMotionPrediction = 4, 33 | }; 34 | 35 | struct ID2DXContext abstract : 36 | public IGlide3x, 37 | public IWin32InterceptionHandler, 38 | public ID2InterceptionHandler 39 | { 40 | virtual ~ID2DXContext() noexcept {} 41 | 42 | virtual void SetCustomResolution( 43 | _In_ Size size) = 0; 44 | 45 | virtual Size GetSuggestedCustomResolution() = 0; 46 | 47 | virtual GameVersion GetGameVersion() const = 0; 48 | 49 | virtual void DisableBuiltinResMod() = 0; 50 | 51 | virtual const Options& GetOptions() const = 0; 52 | 53 | virtual bool IsFeatureEnabled( 54 | _In_ Feature feature) = 0; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /src/d2dx/ID2InterceptionHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IGameHelper.h" 22 | #include "Types.h" 23 | #include "D2Types.h" 24 | 25 | namespace d2dx 26 | { 27 | struct ID2InterceptionHandler abstract 28 | { 29 | virtual ~ID2InterceptionHandler() noexcept {} 30 | 31 | virtual Offset BeginDrawText( 32 | _Inout_z_ wchar_t* str, 33 | _In_ Offset pos, 34 | _In_ uint32_t returnAddress, 35 | _In_ D2Function d2Function) = 0; 36 | 37 | virtual void EndDrawText() = 0; 38 | 39 | virtual Offset BeginDrawImage( 40 | _In_ const D2::CellContext* cellContext, 41 | _In_ uint32_t drawMode, 42 | _In_ Offset pos, 43 | _In_ D2Function d2Function) = 0; 44 | 45 | virtual void EndDrawImage() = 0; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /src/d2dx/IGameHelper.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Types.h" 22 | #include "D2Types.h" 23 | 24 | namespace d2dx 25 | { 26 | enum class D2Function 27 | { 28 | D2Gfx_DrawImage = 0, /* call dword ptr [eax+84h] */ 29 | D2Gfx_DrawShiftedImage = 1, /* call dword ptr [eax+88h] */ 30 | D2Gfx_DrawVerticalCropImage = 2, /* call dword ptr [eax+8Ch] */ 31 | D2Gfx_DrawClippedImage = 3, /* call dword ptr [eax+98h] */ 32 | D2Gfx_DrawImageFast = 4, /* call dword ptr [eax+94h] */ 33 | D2Gfx_DrawShadow = 5, /* call dword ptr [eax+90h] */ 34 | D2Win_DrawText = 6, /* mov ebx, [esp+4+arg_8] */ 35 | D2Win_DrawTextEx = 7, 36 | D2Win_DrawFramedText = 8, 37 | D2Win_DrawRectangledText = 9, /* setle cl */ 38 | D2Client_DrawUnit = 10, /* push 52Bh */ 39 | D2Client_DrawMissile = 11, 40 | D2Client_DrawWeatherParticles = 12, 41 | D2Client_FindClientSideUnit = 13, 42 | D2Client_FindServerSideUnit = 14, 43 | }; 44 | 45 | struct DrawParameters 46 | { 47 | uint32_t unitId; 48 | uint32_t unitType; 49 | uint32_t unitToken; 50 | }; 51 | 52 | struct IGameHelper abstract 53 | { 54 | virtual ~IGameHelper() noexcept {} 55 | 56 | virtual GameVersion GetVersion() const = 0; 57 | 58 | virtual _Ret_z_ const char* GetVersionString() const = 0; 59 | 60 | virtual uint32_t ScreenOpenMode() const = 0; 61 | 62 | virtual Size GetConfiguredGameSize() const = 0; 63 | 64 | virtual GameAddress IdentifyGameAddress( 65 | _In_ uint32_t returnAddress) const = 0; 66 | 67 | virtual TextureCategory GetTextureCategoryFromHash( 68 | _In_ uint32_t textureHash) const = 0; 69 | 70 | virtual TextureCategory RefineTextureCategoryFromGameAddress( 71 | _In_ TextureCategory previousCategory, 72 | _In_ GameAddress gameAddress) const = 0; 73 | 74 | virtual bool TryApplyInGameFpsFix() = 0; 75 | 76 | virtual bool TryApplyMenuFpsFix() = 0; 77 | 78 | virtual bool TryApplyInGameSleepFixes() = 0; 79 | 80 | virtual void* GetFunction( 81 | _In_ D2Function function) const = 0; 82 | 83 | virtual DrawParameters GetDrawParameters( 84 | _In_ const D2::CellContext* cellContext) const = 0; 85 | 86 | virtual D2::UnitAny* GetPlayerUnit() const = 0; 87 | 88 | virtual Offset GetUnitPos( 89 | _In_ const D2::UnitAny* unit) const = 0; 90 | 91 | virtual D2::UnitType GetUnitType( 92 | _In_ const D2::UnitAny* unit) const = 0; 93 | 94 | virtual uint32_t GetUnitId( 95 | _In_ const D2::UnitAny* unit) const = 0; 96 | 97 | virtual D2::UnitAny* FindUnit( 98 | _In_ uint32_t unitId, 99 | _In_ D2::UnitType unitType) const = 0; 100 | 101 | virtual int32_t GetCurrentAct() const = 0; 102 | 103 | virtual bool IsGameMenuOpen() const = 0; 104 | 105 | virtual bool IsInGame() const = 0; 106 | 107 | virtual bool IsProjectDiablo2() const = 0; 108 | }; 109 | } 110 | -------------------------------------------------------------------------------- /src/d2dx/IGlide3x.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Types.h" 22 | 23 | namespace d2dx 24 | { 25 | struct IGlide3x abstract 26 | { 27 | virtual ~IGlide3x() noexcept {} 28 | 29 | virtual const char* OnGetString( 30 | _In_ uint32_t pname) = 0; 31 | 32 | virtual uint32_t OnGet( 33 | _In_ uint32_t pname, 34 | _In_ uint32_t plength, 35 | _Out_writes_(plength) int32_t* params) = 0; 36 | 37 | virtual void OnSstWinOpen( 38 | _In_ uint32_t hWnd, 39 | _In_ int32_t width, 40 | _In_ int32_t height) = 0; 41 | 42 | virtual void OnVertexLayout( 43 | _In_ uint32_t param, 44 | _In_ int32_t offset) = 0; 45 | 46 | virtual void OnTexDownload( 47 | _In_ uint32_t tmu, 48 | _In_reads_(width* height) const uint8_t* sourceAddress, 49 | _In_ uint32_t startAddress, 50 | _In_ int32_t width, 51 | _In_ int32_t height) = 0; 52 | 53 | virtual void OnTexSource( 54 | _In_ uint32_t tmu, 55 | _In_ uint32_t startAddress, 56 | _In_ int32_t width, 57 | _In_ int32_t height) = 0; 58 | 59 | virtual void OnConstantColorValue( 60 | _In_ uint32_t color) = 0; 61 | 62 | virtual void OnAlphaBlendFunction( 63 | _In_ GrAlphaBlendFnc_t rgb_sf, 64 | _In_ GrAlphaBlendFnc_t rgb_df, 65 | _In_ GrAlphaBlendFnc_t alpha_sf, 66 | _In_ GrAlphaBlendFnc_t alpha_df) = 0; 67 | 68 | virtual void OnColorCombine( 69 | _In_ GrCombineFunction_t function, 70 | _In_ GrCombineFactor_t factor, 71 | _In_ GrCombineLocal_t local, 72 | _In_ GrCombineOther_t other, 73 | _In_ bool invert) = 0; 74 | 75 | virtual void OnAlphaCombine( 76 | _In_ GrCombineFunction_t function, 77 | _In_ GrCombineFactor_t factor, 78 | _In_ GrCombineLocal_t local, 79 | _In_ GrCombineOther_t other, 80 | _In_ bool invert) = 0; 81 | 82 | virtual void OnDrawPoint( 83 | _In_ const void* pt, 84 | _In_ uint32_t gameContext) = 0; 85 | 86 | virtual void OnDrawLine( 87 | _In_ const void* v1, 88 | _In_ const void* v2, 89 | _In_ uint32_t gameContext) = 0; 90 | 91 | virtual void OnDrawVertexArray( 92 | _In_ uint32_t mode, 93 | _In_ uint32_t count, 94 | _In_reads_(count) uint8_t** pointers, 95 | _In_ uint32_t gameContext) = 0; 96 | 97 | virtual void OnDrawVertexArrayContiguous( 98 | _In_ uint32_t mode, 99 | _In_ uint32_t count, 100 | _In_reads_(count* stride) uint8_t* vertex, 101 | _In_ uint32_t stride, 102 | _In_ uint32_t gameContext) = 0; 103 | 104 | virtual void OnTexDownloadTable( 105 | _In_ GrTexTable_t type, 106 | _In_reads_bytes_(256 * 4) void* data) = 0; 107 | 108 | virtual void OnLoadGammaTable( 109 | _In_ uint32_t nentries, 110 | _In_reads_(nentries) uint32_t* red, 111 | _In_reads_(nentries) uint32_t* green, 112 | _In_reads_(nentries) uint32_t* blue) = 0; 113 | 114 | virtual void OnChromakeyMode( 115 | _In_ GrChromakeyMode_t mode) = 0; 116 | 117 | virtual void OnLfbUnlock( 118 | _In_reads_bytes_(strideInBytes * 480) const uint32_t* lfbPtr, 119 | _In_ uint32_t strideInBytes) = 0; 120 | 121 | virtual void OnGammaCorrectionRGB( 122 | _In_ float red, 123 | _In_ float green, 124 | _In_ float blue) = 0; 125 | 126 | virtual void OnBufferSwap() = 0; 127 | 128 | virtual void OnBufferClear() = 0; 129 | }; 130 | } 131 | -------------------------------------------------------------------------------- /src/d2dx/IRenderContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ITextureCache.h" 22 | #include "Types.h" 23 | #include "Options.h" 24 | 25 | namespace d2dx 26 | { 27 | class Vertex; 28 | class Batch; 29 | 30 | struct IRenderContext abstract 31 | { 32 | virtual ~IRenderContext() noexcept {} 33 | 34 | virtual HWND GetHWnd() const = 0; 35 | 36 | virtual void LoadGammaTable( 37 | _In_reads_(valueCount) const uint32_t* values, 38 | _In_ uint32_t valueCount) = 0; 39 | 40 | virtual uint32_t BulkWriteVertices( 41 | _In_reads_(vertexCount) const Vertex* vertices, 42 | _In_ uint32_t vertexCount) = 0; 43 | 44 | virtual TextureCacheLocation UpdateTexture( 45 | _In_ const Batch& batch, 46 | _In_reads_(tmuDataSize) const uint8_t* tmuData, 47 | _In_ uint32_t tmuDataSize) = 0; 48 | 49 | virtual void Draw( 50 | _In_ const Batch& batch, 51 | _In_ uint32_t startVertexLocation) = 0; 52 | 53 | virtual void Present() = 0; 54 | 55 | virtual void WriteToScreen( 56 | _In_reads_(width * height) const uint32_t* pixels, 57 | _In_ int32_t width, 58 | _In_ int32_t height) = 0; 59 | 60 | virtual void SetPalette( 61 | _In_ int32_t paletteIndex, 62 | _In_reads_(256) const uint32_t* palette) = 0; 63 | 64 | virtual const Options& GetOptions() const = 0; 65 | 66 | virtual ITextureCache* GetTextureCache( 67 | _In_ const Batch& batch) const = 0; 68 | 69 | virtual void SetSizes( 70 | _In_ Size gameSize, 71 | _In_ Size windowSize) = 0; 72 | 73 | virtual void GetCurrentMetrics( 74 | _Out_opt_ Size* gameSize, 75 | _Out_opt_ Rect* renderRect, 76 | _Out_opt_ Size* desktopSize) const = 0; 77 | 78 | virtual void ToggleFullscreen() = 0; 79 | 80 | virtual float GetFrameTime() const = 0; 81 | 82 | virtual int32_t GetFrameTimeFp() const = 0; 83 | 84 | virtual ScreenMode GetScreenMode() const = 0; 85 | }; 86 | } 87 | -------------------------------------------------------------------------------- /src/d2dx/ISimd.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Utils.h" 22 | 23 | namespace d2dx 24 | { 25 | struct ISimd abstract 26 | { 27 | virtual ~ISimd() noexcept {} 28 | 29 | virtual int32_t IndexOfUInt32( 30 | _In_reads_(itemsCount) const uint32_t* __restrict items, 31 | _In_ uint32_t itemsCount, 32 | _In_ uint32_t item) = 0; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /src/d2dx/ITextureCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ISimd.h" 22 | #include "Types.h" 23 | 24 | namespace d2dx 25 | { 26 | class Batch; 27 | 28 | struct TextureCacheLocation final 29 | { 30 | int16_t _textureAtlas; 31 | int16_t _textureIndex; 32 | }; 33 | 34 | static_assert(sizeof(TextureCacheLocation) == 4, "sizeof(TextureCacheLocation) == 4"); 35 | 36 | struct ITextureCache abstract 37 | { 38 | virtual ~ITextureCache() noexcept {} 39 | 40 | virtual void OnNewFrame() = 0; 41 | 42 | virtual TextureCacheLocation FindTexture( 43 | _In_ uint32_t contentKey, 44 | _In_ int32_t lastIndex) = 0; 45 | 46 | virtual TextureCacheLocation InsertTexture( 47 | _In_ uint32_t contentKey, 48 | _In_ const Batch& batch, 49 | _In_reads_(tmuDataSize) const uint8_t* tmuData, 50 | _In_ uint32_t tmuDataSize) = 0; 51 | 52 | virtual ID3D11ShaderResourceView* GetSrv( 53 | _In_ uint32_t atlasIndex) const = 0; 54 | 55 | virtual uint32_t GetMemoryFootprint() const = 0; 56 | 57 | virtual uint32_t GetUsedCount() const = 0; 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /src/d2dx/IWin32InterceptionHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Types.h" 22 | 23 | namespace d2dx 24 | { 25 | struct IWin32InterceptionHandler abstract 26 | { 27 | virtual ~IWin32InterceptionHandler() noexcept {} 28 | 29 | virtual Offset OnSetCursorPos( 30 | _In_ Offset pos) = 0; 31 | 32 | virtual Offset OnMouseMoveMessage( 33 | _In_ Offset pos) = 0; 34 | 35 | virtual int32_t OnSleep( 36 | _In_ int32_t ms) = 0; 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/d2dx/Metrics.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Metrics.h" 3 | 4 | using namespace d2dx; 5 | using namespace DirectX; 6 | 7 | struct MetricsTableEntry final 8 | { 9 | Size desktopSize; 10 | Size gameSize; 11 | Size gameSizeWide; 12 | }; 13 | 14 | static const struct MetricsTableEntry metricsTable[] = 15 | { 16 | { 17 | .desktopSize { 1280, 720 }, 18 | .gameSize { 960, 720 }, 19 | .gameSizeWide { 1280, 720 }, 20 | }, 21 | { 22 | .desktopSize { 1360, 768 }, 23 | .gameSize { 1024, 768 }, 24 | .gameSizeWide { 1360, 768 }, 25 | }, 26 | { 27 | .desktopSize { 1366, 768 }, 28 | .gameSize { 1024, 768 }, 29 | .gameSizeWide { 1366, 768 }, 30 | }, 31 | { 32 | .desktopSize { 1280, 800 }, 33 | .gameSize { 1066, 800 }, 34 | .gameSizeWide { 1280, 800 }, 35 | }, 36 | { 37 | .desktopSize { 1536, 864 }, 38 | .gameSize { 1152, 864 }, 39 | .gameSizeWide { 1536, 864 }, 40 | }, 41 | { 42 | .desktopSize { 1440, 900 }, 43 | .gameSize { 1200, 900 }, 44 | .gameSizeWide { 1440, 900 }, 45 | }, 46 | { 47 | .desktopSize { 1600, 900 }, 48 | .gameSize { 1200, 900 }, 49 | .gameSizeWide { 1600, 900 }, 50 | }, 51 | { 52 | .desktopSize { 1280, 1024 }, 53 | .gameSize { 640, 480 }, 54 | .gameSizeWide { 640, 512 }, 55 | }, 56 | { 57 | .desktopSize { 1400, 1050 }, 58 | .gameSize { 700, 525 }, 59 | .gameSizeWide { 700, 525 }, 60 | }, 61 | { 62 | .desktopSize { 1680, 1050 }, 63 | .gameSize { 700, 525 }, 64 | .gameSizeWide { 840, 525 }, 65 | }, 66 | { 67 | .desktopSize { 1920, 1080 }, 68 | .gameSize { 720, 540 }, 69 | .gameSizeWide { 960, 540 }, 70 | }, 71 | { 72 | .desktopSize { 2560, 1080 }, 73 | .gameSize { 720, 540 }, 74 | .gameSizeWide { 960, 540 }, /* note: doesn't cover entire monitor */ 75 | }, 76 | { 77 | .desktopSize { 2048, 1152 }, 78 | .gameSize { 768, 576 }, 79 | .gameSizeWide { 1024, 576 }, 80 | }, 81 | { 82 | .desktopSize { 1600, 1200 }, 83 | .gameSize { 800, 600 }, 84 | .gameSizeWide { 800, 600 }, 85 | }, 86 | { 87 | .desktopSize { 1920, 1200 }, 88 | .gameSize { 800, 600 }, 89 | .gameSizeWide { 960, 600 }, 90 | }, 91 | { 92 | .desktopSize { 2560, 1440 }, 93 | .gameSize { 960, 720 }, 94 | .gameSizeWide { 1280, 720 }, 95 | }, 96 | { 97 | .desktopSize { 3440, 1440 }, 98 | .gameSize { 960, 720 }, 99 | .gameSizeWide { 1280, 720 }, /* note: doesn't cover entire monitor */ 100 | }, 101 | { 102 | .desktopSize { 2048, 1536 }, 103 | .gameSize { 1024, 768 }, 104 | .gameSizeWide { 1024, 768 }, 105 | }, 106 | { 107 | .desktopSize { 2560, 1600 }, 108 | .gameSize { 710, 532 }, 109 | .gameSizeWide { 852, 532 }, 110 | }, 111 | { 112 | .desktopSize { 2560, 2048 }, 113 | .gameSize { 852, 640 }, 114 | .gameSizeWide { 852, 682 }, 115 | }, 116 | { 117 | .desktopSize { 3200, 2048 }, 118 | .gameSize { 852, 640 }, 119 | .gameSizeWide { 1066, 682 }, 120 | }, 121 | { 122 | .desktopSize { 3840, 2160 }, 123 | .gameSize { 960, 720 }, 124 | .gameSizeWide { 1280, 720 }, 125 | }, 126 | { 127 | .desktopSize { 4096, 2160 }, 128 | .gameSize { 960, 720 }, 129 | .gameSizeWide { 1364, 720 }, 130 | }, 131 | { 132 | .desktopSize { 4320, 2160 }, 133 | .gameSize { 960, 720 }, 134 | .gameSizeWide { 1440, 720 }, 135 | }, 136 | { 137 | .desktopSize { 3200, 2400 }, 138 | .gameSize { 800, 600 }, 139 | .gameSizeWide { 800, 600 }, 140 | }, 141 | { 142 | .desktopSize { 3840, 2400 }, 143 | .gameSize { 800, 600 }, 144 | .gameSizeWide { 960, 600 }, 145 | }, 146 | }; 147 | 148 | _Use_decl_annotations_ 149 | Size d2dx::Metrics::GetSuggestedGameSize( 150 | Size desktopSize, 151 | bool wide) noexcept 152 | { 153 | for (int32_t i = 0; i < ARRAYSIZE(metricsTable); ++i) 154 | { 155 | if (metricsTable[i].desktopSize.width == desktopSize.width && 156 | metricsTable[i].desktopSize.height == desktopSize.height) 157 | { 158 | return wide ? metricsTable[i].gameSizeWide : metricsTable[i].gameSize; 159 | } 160 | } 161 | 162 | Size size = { 0, 0 }; 163 | for (int32_t scaleFactor = 1; scaleFactor <= 8; ++scaleFactor) 164 | { 165 | size.width = desktopSize.width / scaleFactor; 166 | size.height = desktopSize.height / scaleFactor; 167 | if ((desktopSize.height / (scaleFactor + 1)) <= 600) 168 | { 169 | break; 170 | } 171 | } 172 | 173 | if (size.height > 720) 174 | { 175 | const float aspect = (float)desktopSize.width / desktopSize.height; 176 | size.width = (int32_t)(aspect * 720); 177 | size.height = 720; 178 | } 179 | 180 | return size; 181 | } 182 | 183 | _Use_decl_annotations_ 184 | Rect d2dx::Metrics::GetRenderRect( 185 | Size gameSize, 186 | Size desktopSize, 187 | bool wide) noexcept 188 | { 189 | int32_t scaleFactor = 1; 190 | 191 | while ( 192 | gameSize.width * (scaleFactor + 1) <= desktopSize.width && 193 | gameSize.height * (scaleFactor + 1) <= desktopSize.height) 194 | { 195 | ++scaleFactor; 196 | } 197 | 198 | Rect rect 199 | { 200 | (desktopSize.width - gameSize.width * scaleFactor) / 2, 201 | (desktopSize.height - gameSize.height * scaleFactor) / 2, 202 | gameSize.width * scaleFactor, 203 | gameSize.height * scaleFactor 204 | }; 205 | 206 | /* Allow for a small amount of black margin on all sides. When more than that, 207 | rescale the image with a non-integer factor. */ 208 | if (rect.offset.x < 0 || rect.offset.y < 0 || (rect.offset.x >= 16 && rect.offset.y >= 16)) 209 | { 210 | float scaleFactorF = (float)desktopSize.width / rect.size.width; 211 | int32_t scaledHeight = (int32_t)(rect.size.height * scaleFactorF); 212 | rect.offset.x = 0; 213 | rect.offset.y = (desktopSize.height - scaledHeight) / 2; 214 | rect.size.width = desktopSize.width; 215 | rect.size.height = scaledHeight; 216 | 217 | if (rect.offset.x < 0 || rect.offset.y < 0) 218 | { 219 | float scaleFactorF = (float)desktopSize.height / rect.size.height; 220 | int32_t scaledWidth = (int32_t)(rect.size.width * scaleFactorF); 221 | rect.offset.x = (desktopSize.width - scaledWidth) / 2; 222 | rect.offset.y = 0; 223 | rect.size.width = scaledWidth; 224 | rect.size.height = desktopSize.height; 225 | } 226 | } 227 | 228 | assert( 229 | rect.offset.x >= 0 && 230 | rect.offset.y >= 0 && 231 | rect.size.width > 0 && 232 | rect.size.height > 0 && 233 | (rect.offset.x + rect.size.width) <= desktopSize.width && 234 | (rect.offset.y + rect.size.height) <= desktopSize.height); 235 | 236 | return rect; 237 | } 238 | 239 | Buffer d2dx::Metrics::GetStandardDesktopSizes() noexcept 240 | { 241 | Buffer standardDesktopSizes(ARRAYSIZE(metricsTable)); 242 | 243 | for (int32_t i = 0; i < ARRAYSIZE(metricsTable); ++i) 244 | { 245 | standardDesktopSizes.items[i] = metricsTable[i].desktopSize; 246 | } 247 | 248 | return standardDesktopSizes; 249 | } 250 | -------------------------------------------------------------------------------- /src/d2dx/Metrics.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Buffer.h" 4 | #include "Types.h" 5 | 6 | namespace d2dx 7 | { 8 | namespace Metrics 9 | { 10 | Size GetSuggestedGameSize( 11 | _In_ Size desktopSize, 12 | _In_ bool wide) noexcept; 13 | 14 | Rect GetRenderRect( 15 | _In_ Size gameSize, 16 | _In_ Size desktopSize, 17 | _In_ bool wide) noexcept; 18 | 19 | Buffer GetStandardDesktopSizes() noexcept; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/d2dx/Options.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "Options.h" 21 | #include "Buffer.h" 22 | #include "Utils.h" 23 | 24 | #include "../../thirdparty/toml/toml.h" 25 | 26 | using namespace d2dx; 27 | 28 | Options::Options() 29 | { 30 | } 31 | 32 | Options::~Options() noexcept 33 | { 34 | } 35 | 36 | _Use_decl_annotations_ 37 | void Options::ApplyCfg( 38 | const char* cfg) 39 | { 40 | auto cfgLen = strlen(cfg); 41 | 42 | if (cfgLen > 65536) 43 | { 44 | D2DX_FATAL_ERROR("Configuration file size limit exceeded."); 45 | } 46 | 47 | Buffer cfgTemp{ cfgLen + 1, true }; 48 | Buffer errorMsg{ 1024, true }; 49 | 50 | strcpy_s(cfgTemp.items, cfgTemp.capacity, cfg); 51 | 52 | auto root = toml_parse(cfgTemp.items, errorMsg.items, errorMsg.capacity); 53 | 54 | if (!root) 55 | { 56 | return; 57 | } 58 | 59 | toml_table_t* optouts = toml_table_in(root, "optouts"); 60 | 61 | if (optouts) 62 | { 63 | toml_datum_t datum; 64 | 65 | #define READ_OPTOUTS_FLAG(flag, cfgStringName) \ 66 | datum = toml_bool_in(optouts, cfgStringName); \ 67 | if (datum.ok) \ 68 | { \ 69 | SetFlag(flag, datum.u.b); \ 70 | } 71 | 72 | READ_OPTOUTS_FLAG(OptionsFlag::NoClipCursor, "noclipcursor"); 73 | READ_OPTOUTS_FLAG(OptionsFlag::NoFpsFix, "nofpsfix"); 74 | READ_OPTOUTS_FLAG(OptionsFlag::NoResMod, "noresmod"); 75 | READ_OPTOUTS_FLAG(OptionsFlag::NoWide, "nowide"); 76 | READ_OPTOUTS_FLAG(OptionsFlag::NoLogo, "nologo"); 77 | READ_OPTOUTS_FLAG(OptionsFlag::NoVSync, "novsync"); 78 | READ_OPTOUTS_FLAG(OptionsFlag::NoAntiAliasing, "noaa"); 79 | READ_OPTOUTS_FLAG(OptionsFlag::NoCompatModeFix, "nocompatmodefix"); 80 | READ_OPTOUTS_FLAG(OptionsFlag::NoTitleChange, "notitlechange"); 81 | READ_OPTOUTS_FLAG(OptionsFlag::NoMotionPrediction, "nomotionprediction"); 82 | 83 | #undef READ_OPTOUTS_FLAG 84 | } 85 | 86 | auto game = toml_table_in(root, "game"); 87 | 88 | if (game) 89 | { 90 | auto gameSize = toml_array_in(game, "size"); 91 | if (gameSize) 92 | { 93 | auto w = toml_int_at(gameSize, 0); 94 | auto h = toml_int_at(gameSize, 1); 95 | 96 | if (w.ok && h.ok) 97 | { 98 | SetUserSpecifiedGameSize({ (int32_t)w.u.i, (int32_t)h.u.i }); 99 | } 100 | } 101 | 102 | auto filtering = toml_int_in(game, "filtering"); 103 | if (filtering.ok) 104 | { 105 | _filtering = (FilteringOption)filtering.u.i; 106 | } 107 | } 108 | 109 | auto window = toml_table_in(root, "window"); 110 | 111 | if (window) 112 | { 113 | auto windowScale = toml_int_in(window, "scale"); 114 | if (windowScale.ok) 115 | { 116 | SetWindowScale((int32_t)windowScale.u.i); 117 | } 118 | 119 | auto windowPosition = toml_array_in(window, "position"); 120 | if (windowPosition) 121 | { 122 | auto x = toml_int_at(windowPosition, 0); 123 | auto y = toml_int_at(windowPosition, 1); 124 | 125 | if (x.ok && y.ok) 126 | { 127 | SetWindowPosition({ (int32_t)x.u.i, (int32_t)y.u.i }); 128 | } 129 | } 130 | 131 | auto frameless = toml_bool_in(window, "frameless"); 132 | if (frameless.ok) 133 | { 134 | SetFlag(OptionsFlag::Frameless, frameless.u.b); 135 | } 136 | } 137 | 138 | auto debug = toml_table_in(root, "debug"); 139 | 140 | if (debug) 141 | { 142 | auto dumpTextures = toml_bool_in(debug, "dumptextures"); 143 | if (dumpTextures.ok) 144 | { 145 | SetFlag(OptionsFlag::DbgDumpTextures, dumpTextures.u.b); 146 | } 147 | } 148 | 149 | toml_free(root); 150 | } 151 | 152 | _Use_decl_annotations_ 153 | void Options::ApplyCommandLine( 154 | const char* cmdLine) 155 | { 156 | if (strstr(cmdLine, "-dxnoclipcursor")) SetFlag(OptionsFlag::NoClipCursor, true); 157 | if (strstr(cmdLine, "-dxnofpsfix")) SetFlag(OptionsFlag::NoFpsFix, true); 158 | if (strstr(cmdLine, "-dxnoresmod")) SetFlag(OptionsFlag::NoResMod, true); 159 | if (strstr(cmdLine, "-dxnowide")) SetFlag(OptionsFlag::NoWide, true); 160 | if (strstr(cmdLine, "-dxnologo")) SetFlag(OptionsFlag::NoLogo, true); 161 | if (strstr(cmdLine, "-dxnovsync")) SetFlag(OptionsFlag::NoVSync, true); 162 | if (strstr(cmdLine, "-dxnoaa")) SetFlag(OptionsFlag::NoAntiAliasing, true); 163 | if (strstr(cmdLine, "-dxnocompatmodefix")) SetFlag(OptionsFlag::NoCompatModeFix, true); 164 | if (strstr(cmdLine, "-dxnotitlechange")) SetFlag(OptionsFlag::NoTitleChange, true); 165 | if (strstr(cmdLine, "-dxnomop")) SetFlag(OptionsFlag::NoMotionPrediction, true); 166 | 167 | if (strstr(cmdLine, "-dxscale3")) SetWindowScale(3); 168 | else if (strstr(cmdLine, "-dxscale2")) SetWindowScale(2); 169 | 170 | if (strstr(cmdLine, "-dxdbg_dump_textures")) SetFlag(OptionsFlag::DbgDumpTextures, true); 171 | } 172 | 173 | _Use_decl_annotations_ 174 | bool Options::GetFlag( 175 | OptionsFlag flag) const 176 | { 177 | return (_flags & (1 << (int32_t)flag)) != 0; 178 | } 179 | 180 | _Use_decl_annotations_ 181 | void Options::SetFlag( 182 | OptionsFlag flag, 183 | bool value) 184 | { 185 | uint32_t mask = 1 << (int32_t)flag; 186 | _flags &= ~mask; 187 | if (value) 188 | { 189 | _flags |= mask; 190 | } 191 | } 192 | 193 | int32_t Options::GetWindowScale() const 194 | { 195 | return _windowScale; 196 | } 197 | 198 | void Options::SetWindowScale( 199 | _In_ int32_t windowScale) 200 | { 201 | _windowScale = min(3, max(1, windowScale)); 202 | } 203 | 204 | Offset Options::GetWindowPosition() const 205 | { 206 | return _windowPosition; 207 | } 208 | 209 | void Options::SetWindowPosition( 210 | _In_ Offset windowPosition) 211 | { 212 | _windowPosition = { max(-1, windowPosition.x), max(-1, windowPosition.y) }; 213 | } 214 | 215 | Size Options::GetUserSpecifiedGameSize() const 216 | { 217 | return _userSpecifiedGameSize; 218 | } 219 | 220 | void Options::SetUserSpecifiedGameSize( 221 | _In_ Size size) 222 | { 223 | _userSpecifiedGameSize = { max(-1, size.width), max(-1, size.height) }; 224 | } 225 | 226 | FilteringOption Options::GetFiltering() const 227 | { 228 | return _filtering; 229 | } 230 | -------------------------------------------------------------------------------- /src/d2dx/Options.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Types.h" 22 | 23 | namespace d2dx 24 | { 25 | enum class OptionsFlag 26 | { 27 | NoClipCursor, 28 | NoFpsFix, 29 | NoResMod, 30 | NoWide, 31 | NoLogo, 32 | NoAntiAliasing, 33 | NoCompatModeFix, 34 | NoTitleChange, 35 | NoVSync, 36 | NoMotionPrediction, 37 | 38 | DbgDumpTextures, 39 | 40 | Frameless, 41 | 42 | Count 43 | }; 44 | 45 | enum class FilteringOption 46 | { 47 | HighQuality = 0, 48 | Bilinear = 1, 49 | CatmullRom = 2, 50 | Count = 3 51 | }; 52 | 53 | class Options final 54 | { 55 | public: 56 | Options(); 57 | ~Options() noexcept; 58 | 59 | void ApplyCfg( 60 | _In_z_ const char* cfg); 61 | 62 | void ApplyCommandLine( 63 | _In_z_ const char* cmdLine); 64 | 65 | bool GetFlag( 66 | _In_ OptionsFlag flag) const; 67 | 68 | void SetFlag( 69 | _In_ OptionsFlag flag, 70 | _In_ bool value); 71 | 72 | int32_t GetWindowScale() const; 73 | 74 | void SetWindowScale( 75 | _In_ int32_t zoomLevel); 76 | 77 | Offset GetWindowPosition() const; 78 | 79 | void SetWindowPosition( 80 | _In_ Offset windowPosition); 81 | 82 | Size GetUserSpecifiedGameSize() const; 83 | 84 | void SetUserSpecifiedGameSize( 85 | _In_ Size size); 86 | 87 | FilteringOption GetFiltering() const; 88 | 89 | private: 90 | uint32_t _flags = 0; 91 | int32_t _windowScale = 1; 92 | Offset _windowPosition{ -1, -1 }; 93 | Size _userSpecifiedGameSize{ -1, -1 }; 94 | FilteringOption _filtering{ FilteringOption::HighQuality }; 95 | }; 96 | } -------------------------------------------------------------------------------- /src/d2dx/ResolveAA.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | //#define SHOW_SURFACE_IDS 23 | //#define SHOW_MASK 24 | //#define SHOW_AMPLIFIED_DIFFERENCE 25 | 26 | Texture2D sceneTexture : register(t0); 27 | Texture2D idTexture : register(t1); 28 | 29 | #define FXAA_PC 1 30 | #define FXAA_HLSL_4 1 31 | #define FXAA_QUALITY__PRESET 23 32 | #include "FXAA.hlsli" 33 | 34 | float4 main( 35 | in DisplayPSInput ps_in) : SV_TARGET 36 | { 37 | float4 c = sceneTexture.SampleLevel(PointSampler, ps_in.tc, 0); 38 | 39 | /* 40 | A B C 41 | D E F 42 | G H I 43 | */ 44 | 45 | float2 tcShifted = ps_in.tc - 0.5 * ps_in.textureSize_invTextureSize.zw; 46 | 47 | float idC = idTexture.SampleLevel(PointSampler, ps_in.tc, 0, int2(1,-1)); 48 | float4 idDEBA = idTexture.Gather(BilinearSampler, tcShifted); 49 | float4 idHIFE = idTexture.Gather(BilinearSampler, tcShifted, int2(1, 1)); 50 | float idG = idTexture.SampleLevel(PointSampler, ps_in.tc, 0, int2(-1, 1)); 51 | 52 | bool isEdge = 53 | idDEBA.y < (1.0-1.0/16383.0) && (idG != idC || any(idDEBA - idC) || any(idHIFE - idC)); 54 | 55 | if (isEdge) 56 | { 57 | #ifdef SHOW_MASK 58 | return float4(1, 0, 0, 1); 59 | #else 60 | FxaaTex ftx; 61 | ftx.smpl = BilinearSampler; 62 | ftx.tex = sceneTexture; 63 | 64 | #ifdef SHOW_AMPLIFIED_DIFFERENCE 65 | float4 oldc = c; 66 | #endif 67 | c = FxaaPixelShader(c, ps_in.tc, ftx, ps_in.textureSize_invTextureSize.zw, 0.5, 0.166, 0.166 * 0.5); 68 | #ifdef SHOW_AMPLIFIED_DIFFERENCE 69 | c.rgb = 0.5 + 4*(c.rgb - oldc.rgb); 70 | #endif 71 | #endif 72 | } 73 | #if defined(SHOW_MASK) || defined(SHOW_AMPLIFIED_DIFFERENCE) 74 | else 75 | { 76 | return float4(0.5, 0.5, 0.5, 1); 77 | } 78 | #endif 79 | 80 | #ifdef SHOW_SURFACE_IDS 81 | uint iid = (uint)(idTexture.SampleLevel(PointSampler, ps_in.tc, 0).x * 16383.0); 82 | float3 idc; 83 | idc.r = (iid & 31) / 31.0; 84 | idc.g = ((iid >> 5) & 31) / 31.0; 85 | idc.b = ((iid >> 10) & 15) / 15.0; 86 | c.rgb = lerp(c.rgb, isEdge ? 1 - idc : idc, 0.5); 87 | #endif 88 | 89 | return c; 90 | } 91 | -------------------------------------------------------------------------------- /src/d2dx/SimdSse2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "SimdSse2.h" 21 | 22 | using namespace d2dx; 23 | using namespace std; 24 | 25 | _Use_decl_annotations_ 26 | int32_t SimdSse2::IndexOfUInt32( 27 | const uint32_t* __restrict items, 28 | uint32_t itemsCount, 29 | uint32_t item) 30 | { 31 | assert(items && ((uintptr_t)items & 63) == 0); 32 | assert(!(itemsCount & 0x3F)); 33 | 34 | const __m128i key4 = _mm_set1_epi32(item); 35 | 36 | int32_t findIndex = -1; 37 | uint32_t i = 0; 38 | uint64_t res = 0; 39 | 40 | /* Note: don't tweak this loop. It manages to fit within the XMM registers on x86 41 | and any change could cause temporaries to spill onto the stack. */ 42 | 43 | for (; i < itemsCount; i += 64) 44 | { 45 | const __m128i ck0 = _mm_load_si128((const __m128i*) & items[i + 0]); 46 | const __m128i ck1 = _mm_load_si128((const __m128i*) & items[i + 4]); 47 | const __m128i ck2 = _mm_load_si128((const __m128i*) & items[i + 8]); 48 | const __m128i ck3 = _mm_load_si128((const __m128i*) & items[i + 12]); 49 | const __m128i ck4 = _mm_load_si128((const __m128i*) & items[i + 16]); 50 | const __m128i ck5 = _mm_load_si128((const __m128i*) & items[i + 20]); 51 | const __m128i ck6 = _mm_load_si128((const __m128i*) & items[i + 24]); 52 | const __m128i ck7 = _mm_load_si128((const __m128i*) & items[i + 28]); 53 | 54 | const __m128i cmp0 = _mm_cmpeq_epi32(key4, ck0); 55 | const __m128i cmp1 = _mm_cmpeq_epi32(key4, ck1); 56 | const __m128i cmp2 = _mm_cmpeq_epi32(key4, ck2); 57 | const __m128i cmp3 = _mm_cmpeq_epi32(key4, ck3); 58 | const __m128i cmp4 = _mm_cmpeq_epi32(key4, ck4); 59 | const __m128i cmp5 = _mm_cmpeq_epi32(key4, ck5); 60 | const __m128i cmp6 = _mm_cmpeq_epi32(key4, ck6); 61 | const __m128i cmp7 = _mm_cmpeq_epi32(key4, ck7); 62 | 63 | const __m128i pack01 = _mm_packs_epi32(cmp0, cmp1); 64 | const __m128i pack23 = _mm_packs_epi32(cmp2, cmp3); 65 | const __m128i pack45 = _mm_packs_epi32(cmp4, cmp5); 66 | const __m128i pack67 = _mm_packs_epi32(cmp6, cmp7); 67 | 68 | const __m128i pack0123 = _mm_packs_epi16(pack01, pack23); 69 | const __m128i pack4567 = _mm_packs_epi16(pack45, pack67); 70 | 71 | const __m128i ck8 = _mm_load_si128((const __m128i*) & items[i + 32]); 72 | const __m128i ck9 = _mm_load_si128((const __m128i*) & items[i + 36]); 73 | const __m128i ckA = _mm_load_si128((const __m128i*) & items[i + 40]); 74 | const __m128i ckB = _mm_load_si128((const __m128i*) & items[i + 44]); 75 | const __m128i ckC = _mm_load_si128((const __m128i*) & items[i + 48]); 76 | const __m128i ckD = _mm_load_si128((const __m128i*) & items[i + 52]); 77 | const __m128i ckE = _mm_load_si128((const __m128i*) & items[i + 56]); 78 | const __m128i ckF = _mm_load_si128((const __m128i*) & items[i + 60]); 79 | 80 | const __m128i cmp8 = _mm_cmpeq_epi32(key4, ck8); 81 | const __m128i cmp9 = _mm_cmpeq_epi32(key4, ck9); 82 | const __m128i cmpA = _mm_cmpeq_epi32(key4, ckA); 83 | const __m128i cmpB = _mm_cmpeq_epi32(key4, ckB); 84 | const __m128i cmpC = _mm_cmpeq_epi32(key4, ckC); 85 | const __m128i cmpD = _mm_cmpeq_epi32(key4, ckD); 86 | const __m128i cmpE = _mm_cmpeq_epi32(key4, ckE); 87 | const __m128i cmpF = _mm_cmpeq_epi32(key4, ckF); 88 | 89 | const __m128i pack89 = _mm_packs_epi32(cmp8, cmp9); 90 | const __m128i packAB = _mm_packs_epi32(cmpA, cmpB); 91 | const __m128i packCD = _mm_packs_epi32(cmpC, cmpD); 92 | const __m128i packEF = _mm_packs_epi32(cmpE, cmpF); 93 | 94 | const __m128i pack89AB = _mm_packs_epi16(pack89, packAB); 95 | const __m128i packCDEF = _mm_packs_epi16(packCD, packEF); 96 | 97 | const uint32_t res01234567 = (uint32_t)_mm_movemask_epi8(pack0123) | ((uint32_t)_mm_movemask_epi8(pack4567) << 16); 98 | const uint32_t res89ABCDEF = (uint32_t)_mm_movemask_epi8(pack89AB) | ((uint32_t)_mm_movemask_epi8(packCDEF) << 16); 99 | 100 | res = res01234567 | ((uint64_t)res89ABCDEF << 32); 101 | if (res > 0) { 102 | break; 103 | } 104 | } 105 | 106 | if (res > 0) 107 | { 108 | DWORD bitIndex = 0; 109 | if (BitScanReverse64(&bitIndex, res)) 110 | { 111 | findIndex = i + bitIndex; 112 | assert(findIndex >= 0 && findIndex < (int32_t)itemsCount); 113 | assert(items[findIndex] == item); 114 | return findIndex; 115 | } 116 | } 117 | 118 | return -1; 119 | } 120 | -------------------------------------------------------------------------------- /src/d2dx/SimdSse2.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ISimd.h" 22 | 23 | namespace d2dx 24 | { 25 | class SimdSse2 final : public ISimd 26 | { 27 | public: 28 | virtual ~SimdSse2() noexcept {} 29 | 30 | virtual int32_t IndexOfUInt32( 31 | _In_reads_(itemsCount) const uint32_t* __restrict items, 32 | _In_ uint32_t itemsCount, 33 | _In_ uint32_t item) override; 34 | }; 35 | } 36 | -------------------------------------------------------------------------------- /src/d2dx/SurfaceIdTracker.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "SurfaceIdTracker.h" 21 | #include "Batch.h" 22 | #include "Vertex.h" 23 | 24 | using namespace d2dx; 25 | 26 | _Use_decl_annotations_ 27 | SurfaceIdTracker::SurfaceIdTracker( 28 | const std::shared_ptr& gameHelper) : 29 | _gameHelper{ gameHelper } 30 | { 31 | } 32 | 33 | void SurfaceIdTracker::OnNewFrame() 34 | { 35 | _nextSurfaceId = 0; 36 | _previousDrawCallRect = { 0,0,0,0 }; 37 | _previousDrawCallTexture = 0; 38 | _previousSurfaceId = -1; 39 | } 40 | 41 | _Use_decl_annotations_ 42 | void SurfaceIdTracker::UpdateBatchSurfaceId( 43 | Batch& batch, 44 | MajorGameState majorGameState, 45 | Size gameSize, 46 | Vertex* batchVertices, 47 | int32_t batchVerticesCount) 48 | { 49 | uint32_t surfaceId = 0; 50 | 51 | uint64_t drawCallTexture = (uint64_t)batch.GetTextureIndex() | ((uint64_t)batch.GetTextureAtlas() << 32ULL); 52 | 53 | int32_t minx = INT_MAX; 54 | int32_t miny = INT_MAX; 55 | int32_t maxx = INT_MIN; 56 | int32_t maxy = INT_MIN; 57 | 58 | for (uint32_t i = 0; i < batch.GetVertexCount(); ++i) 59 | { 60 | int32_t x = (int32_t)batchVertices[i].GetX(); 61 | int32_t y = (int32_t)batchVertices[i].GetY(); 62 | minx = min(minx, x); 63 | miny = min(miny, y); 64 | maxx = max(maxx, x); 65 | maxy = max(maxy, y); 66 | } 67 | 68 | if (majorGameState != MajorGameState::InGame) 69 | { 70 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 71 | } 72 | else if (!batch.IsChromaKeyEnabled()) 73 | { 74 | /* Text background rectangle. */ 75 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 76 | } 77 | else 78 | { 79 | if (batch.GetGameAddress() == GameAddress::DrawLine && 80 | (maxy - miny) == 1) 81 | { 82 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 83 | } 84 | else if (miny >= (gameSize.height - 48)) 85 | { 86 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 87 | } 88 | else if ((_gameHelper->ScreenOpenMode() & 1) && minx >= gameSize.width / 2) 89 | { 90 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 91 | } 92 | else if ((_gameHelper->ScreenOpenMode() & 2) && maxx <= gameSize.width / 2) 93 | { 94 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 95 | } 96 | else 97 | { 98 | switch (batch.GetTextureCategory()) 99 | { 100 | case TextureCategory::MousePointer: 101 | case TextureCategory::UserInterface: 102 | surfaceId = D2DX_SURFACE_ID_USER_INTERFACE; 103 | break; 104 | default: 105 | case TextureCategory::Floor: 106 | case TextureCategory::Wall: 107 | case TextureCategory::Unknown: 108 | { 109 | bool isNewSurface = true; 110 | 111 | if (_previousDrawCallTexture == drawCallTexture) 112 | { 113 | isNewSurface = false; 114 | } 115 | else if (batch.GetTextureWidth() == 32 && batch.GetTextureHeight() == 32) 116 | { 117 | if (/* 32x32 wall block drawn to the left of the previous one. */ 118 | (maxx == _previousDrawCallRect.offset.x && miny == _previousDrawCallRect.offset.y) || 119 | 120 | /* 32x32 wall block drawn on the next row from the previous one. */ 121 | (miny == (_previousDrawCallRect.offset.y + _previousDrawCallRect.size.height))) 122 | { 123 | isNewSurface = false; 124 | } 125 | } 126 | 127 | if (isNewSurface) 128 | { 129 | surfaceId = ++_nextSurfaceId; 130 | } 131 | else 132 | { 133 | surfaceId = _nextSurfaceId; 134 | } 135 | 136 | break; 137 | } 138 | } 139 | } 140 | 141 | } 142 | 143 | _previousSurfaceId = surfaceId; 144 | 145 | for (uint32_t i = 0; i < batch.GetVertexCount(); ++i) 146 | { 147 | batchVertices[i].SetSurfaceId(surfaceId); 148 | } 149 | _previousDrawCallTexture = drawCallTexture; 150 | _previousDrawCallRect.offset.x = minx; 151 | _previousDrawCallRect.offset.y = miny; 152 | _previousDrawCallRect.size.width = maxx - minx; 153 | _previousDrawCallRect.size.height = maxy - miny; 154 | } 155 | 156 | int32_t SurfaceIdTracker::GetCurrentSurfaceId() const 157 | { 158 | return _nextSurfaceId; 159 | } 160 | -------------------------------------------------------------------------------- /src/d2dx/SurfaceIdTracker.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Types.h" 22 | 23 | namespace d2dx 24 | { 25 | class Batch; 26 | class Vertex; 27 | struct IGameHelper; 28 | 29 | class SurfaceIdTracker final 30 | { 31 | public: 32 | SurfaceIdTracker( 33 | _In_ const std::shared_ptr& gameHelper); 34 | 35 | void OnNewFrame(); 36 | 37 | void UpdateBatchSurfaceId( 38 | _Inout_ Batch& batch, 39 | _In_ MajorGameState majorGameState, 40 | _In_ Size gameSize, 41 | _Inout_updates_all_(batchVerticesCount) Vertex* batchVertices, 42 | _In_ int32_t batchVerticesCount); 43 | 44 | int32_t GetCurrentSurfaceId() const; 45 | 46 | private: 47 | std::shared_ptr _gameHelper; 48 | int32_t _nextSurfaceId = 0; 49 | int32_t _previousSurfaceId = -1; 50 | Rect _previousDrawCallRect = { 0,0,0,0 }; 51 | uint64_t _previousDrawCallTexture = 0; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /src/d2dx/TextMotionPredictor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "TextMotionPredictor.h" 21 | 22 | using namespace d2dx; 23 | using namespace DirectX; 24 | 25 | _Use_decl_annotations_ 26 | TextMotionPredictor::TextMotionPredictor( 27 | const std::shared_ptr& gameHelper) : 28 | _gameHelper{ gameHelper }, 29 | _textMotions{ 128, true }, 30 | _textsCount{ 0 }, 31 | _frame{ 0 } 32 | { 33 | } 34 | 35 | _Use_decl_annotations_ 36 | void TextMotionPredictor::Update( 37 | IRenderContext* renderContext) 38 | { 39 | renderContext->GetCurrentMetrics(&_gameSize, nullptr, nullptr); 40 | 41 | const float dt = renderContext->GetFrameTime(); 42 | int32_t expiredTextIndex = -1; 43 | 44 | for (int32_t i = 0; i < _textsCount; ++i) 45 | { 46 | TextMotion& tm = _textMotions.items[i]; 47 | 48 | if (!tm.id) 49 | { 50 | expiredTextIndex = i; 51 | continue; 52 | } 53 | 54 | if (abs((int64_t)_frame - (int64_t)tm.lastUsedFrame) > 2) 55 | { 56 | tm.id = 0; 57 | expiredTextIndex = i; 58 | continue; 59 | } 60 | 61 | OffsetF targetVec = tm.targetPos - tm.currentPos; 62 | float targetDistance = targetVec.Length(); 63 | targetVec.Normalize(); 64 | 65 | float step = min(dt * 30.0f * targetDistance, targetDistance); 66 | 67 | auto moveVec = targetVec * step; 68 | 69 | tm.currentPos += moveVec; 70 | } 71 | 72 | // Gradually (one change per frame) compact the list. 73 | if (_textsCount > 0) 74 | { 75 | if (!_textMotions.items[_textsCount - 1].id) 76 | { 77 | // The last entry is expired. Shrink the list. 78 | _textMotions.items[_textsCount - 1] = { }; 79 | --_textsCount; 80 | } 81 | else if (expiredTextIndex >= 0 && expiredTextIndex < (_textsCount - 1)) 82 | { 83 | // Some entry is expired. Move the last entry to that place, and shrink the list. 84 | _textMotions.items[expiredTextIndex] = _textMotions.items[_textsCount - 1]; 85 | _textMotions.items[_textsCount - 1] = { }; 86 | --_textsCount; 87 | } 88 | } 89 | 90 | ++_frame; 91 | } 92 | 93 | _Use_decl_annotations_ 94 | Offset TextMotionPredictor::GetOffset( 95 | uint64_t textId, 96 | Offset posFromGame) 97 | { 98 | OffsetF posFromGameF{ (float)posFromGame.x, (float)posFromGame.y }; 99 | int32_t textIndex = -1; 100 | 101 | for (int32_t i = 0; i < _textsCount; ++i) 102 | { 103 | if (_textMotions.items[i].id == textId) 104 | { 105 | bool resetCurrentPos = false; 106 | 107 | if ((_gameHelper->ScreenOpenMode() & 1) && posFromGameF.x >= _gameSize.width / 2) 108 | { 109 | resetCurrentPos = true; 110 | } 111 | else if ((_gameHelper->ScreenOpenMode() & 2) && posFromGameF.x <= _gameSize.width / 2) 112 | { 113 | resetCurrentPos = true; 114 | } 115 | else 116 | { 117 | auto distance = (posFromGameF - _textMotions.items[i].targetPos).Length(); 118 | if (distance > 32.0f) 119 | { 120 | resetCurrentPos = true; 121 | } 122 | } 123 | 124 | _textMotions.items[i].targetPos = posFromGameF; 125 | if (resetCurrentPos) 126 | { 127 | _textMotions.items[i].currentPos = posFromGameF; 128 | } 129 | _textMotions.items[i].lastUsedFrame = _frame; 130 | textIndex = i; 131 | break; 132 | } 133 | } 134 | 135 | if (textIndex < 0) 136 | { 137 | if (_textsCount < (int32_t)_textMotions.capacity) 138 | { 139 | textIndex = _textsCount++; 140 | _textMotions.items[textIndex].id = textId; 141 | _textMotions.items[textIndex].targetPos = posFromGameF; 142 | _textMotions.items[textIndex].currentPos = posFromGameF; 143 | _textMotions.items[textIndex].lastUsedFrame = _frame; 144 | } 145 | else 146 | { 147 | D2DX_DEBUG_LOG("TMP: Too many texts."); 148 | } 149 | } 150 | 151 | if (textIndex < 0) 152 | { 153 | return { 0, 0 }; 154 | } 155 | 156 | TextMotion& tm = _textMotions.items[textIndex]; 157 | return { (int32_t)(tm.currentPos.x - posFromGame.x), (int32_t)(tm.currentPos.y - posFromGame.y) }; 158 | } 159 | -------------------------------------------------------------------------------- /src/d2dx/TextMotionPredictor.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IGameHelper.h" 22 | #include "IRenderContext.h" 23 | 24 | namespace d2dx 25 | { 26 | class TextMotionPredictor 27 | { 28 | public: 29 | TextMotionPredictor( 30 | _In_ const std::shared_ptr& gameHelper); 31 | 32 | void Update( 33 | _In_ IRenderContext* renderContext); 34 | 35 | Offset GetOffset( 36 | _In_ uint64_t textId, 37 | _In_ Offset posFromGame); 38 | 39 | private: 40 | struct TextMotion final 41 | { 42 | uint64_t id = 0; 43 | uint32_t lastUsedFrame = 0; 44 | OffsetF targetPos = { 0, 0 }; 45 | OffsetF currentPos = { 0, 0 }; 46 | int64_t dtLastPosChange = 0; 47 | }; 48 | 49 | std::shared_ptr _gameHelper; 50 | uint32_t _frame = 0; 51 | Buffer _textMotions; 52 | int32_t _textsCount; 53 | Size _gameSize; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/d2dx/TextureCache.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "D2DXContext.h" 21 | #include "Utils.h" 22 | #include "TextureCache.h" 23 | #include "TextureCachePolicyBitPmru.h" 24 | 25 | using namespace d2dx; 26 | using namespace std; 27 | 28 | _Use_decl_annotations_ 29 | TextureCache::TextureCache( 30 | int32_t width, 31 | int32_t height, 32 | uint32_t capacity, 33 | uint32_t texturesPerAtlas, 34 | ID3D11Device* device, 35 | const std::shared_ptr& simd) 36 | { 37 | assert(_atlasCount <= 4); 38 | 39 | _width = width; 40 | _height = height; 41 | _capacity = capacity; 42 | _texturesPerAtlas = texturesPerAtlas; 43 | _atlasCount = (int32_t)max(1, capacity / texturesPerAtlas); 44 | _policy = TextureCachePolicyBitPmru(capacity, simd); 45 | 46 | #ifndef D2DX_UNITTEST 47 | 48 | CD3D11_TEXTURE2D_DESC desc 49 | { 50 | DXGI_FORMAT_R8_UINT, 51 | (UINT)width, 52 | (UINT)height, 53 | _texturesPerAtlas, 54 | 1U, 55 | D3D11_BIND_SHADER_RESOURCE, 56 | D3D11_USAGE_DEFAULT 57 | }; 58 | 59 | uint32_t capacityPerPartition = _capacity; 60 | 61 | for (int32_t partition = 0; partition < 4; ++partition) 62 | { 63 | D2DX_CHECK_HR(device->CreateTexture2D(&desc, nullptr, &_textures[partition])); 64 | D2DX_CHECK_HR(device->CreateShaderResourceView(_textures[partition].Get(), NULL, _srvs[partition].GetAddressOf())); 65 | } 66 | 67 | device->GetImmediateContext(&_deviceContext); 68 | assert(_deviceContext); 69 | #endif 70 | } 71 | 72 | uint32_t TextureCache::GetMemoryFootprint() const 73 | { 74 | return _width * _height * _texturesPerAtlas * _atlasCount; 75 | } 76 | 77 | _Use_decl_annotations_ 78 | TextureCacheLocation TextureCache::FindTexture( 79 | uint32_t contentKey, 80 | int32_t lastIndex) 81 | { 82 | const int32_t index = _policy.Find(contentKey, lastIndex); 83 | 84 | if (index < 0) 85 | { 86 | return { -1, -1 }; 87 | } 88 | 89 | return { (int16_t)(index / _texturesPerAtlas), (int16_t)(index & (_texturesPerAtlas - 1)) }; 90 | } 91 | 92 | _Use_decl_annotations_ 93 | TextureCacheLocation TextureCache::InsertTexture( 94 | uint32_t contentKey, 95 | const Batch& batch, 96 | const uint8_t* tmuData, 97 | uint32_t tmuDataSize) 98 | { 99 | assert(batch.IsValid() && batch.GetTextureWidth() > 0 && batch.GetTextureHeight() > 0); 100 | 101 | bool evicted = false; 102 | int32_t replacementIndex = _policy.Insert(contentKey, evicted); 103 | 104 | if (evicted) 105 | { 106 | D2DX_DEBUG_LOG("Evicted %ix%i texture %i from cache.", batch.GetTextureWidth(), batch.GetTextureHeight(), replacementIndex); 107 | } 108 | 109 | #ifndef D2DX_UNITTEST 110 | CD3D11_BOX box; 111 | box.left = 0; 112 | box.top = 0; 113 | box.right = batch.GetTextureWidth(); 114 | box.bottom = batch.GetTextureHeight(); 115 | box.front = 0; 116 | box.back = 1; 117 | 118 | const uint8_t* pData = tmuData + batch.GetTextureStartAddress(); 119 | 120 | _deviceContext->UpdateSubresource(_textures[replacementIndex / _texturesPerAtlas].Get(), replacementIndex & (_texturesPerAtlas - 1), &box, pData, batch.GetTextureWidth(), 0); 121 | #endif 122 | 123 | return { (int16_t)(replacementIndex / _texturesPerAtlas), (int16_t)(replacementIndex & (_texturesPerAtlas - 1)) }; 124 | } 125 | 126 | _Use_decl_annotations_ 127 | ID3D11ShaderResourceView* TextureCache::GetSrv( 128 | uint32_t textureAtlas) const 129 | { 130 | assert(textureAtlas >= 0 && textureAtlas < (uint32_t)_atlasCount); 131 | return _srvs[textureAtlas].Get(); 132 | } 133 | 134 | void TextureCache::OnNewFrame() 135 | { 136 | _policy.OnNewFrame(); 137 | } 138 | 139 | _Use_decl_annotations_ 140 | void TextureCache::CopyPixels( 141 | int32_t srcWidth, 142 | int32_t srcHeight, 143 | const uint8_t* __restrict srcPixels, 144 | uint32_t srcPitch, 145 | uint8_t* __restrict dstPixels, 146 | uint32_t dstPitch) 147 | { 148 | const int32_t srcSkip = srcPitch - srcWidth; 149 | const int32_t dstSkip = dstPitch - srcWidth; 150 | 151 | assert(srcSkip >= 0); 152 | assert(dstSkip >= 0); 153 | 154 | for (int32_t y = 0; y < srcHeight; ++y) 155 | { 156 | for (int32_t x = 0; x < srcWidth; ++x) 157 | { 158 | *dstPixels++ = *srcPixels++; 159 | } 160 | srcPixels += srcSkip; 161 | dstPixels += dstSkip; 162 | } 163 | } 164 | 165 | uint32_t TextureCache::GetUsedCount() const 166 | { 167 | return _policy.GetUsedCount(); 168 | } 169 | -------------------------------------------------------------------------------- /src/d2dx/TextureCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ITextureCache.h" 22 | #include "TextureCachePolicyBitPmru.h" 23 | 24 | namespace d2dx 25 | { 26 | class TextureCache final : public ITextureCache 27 | { 28 | public: 29 | TextureCache( 30 | _In_ int32_t width, 31 | _In_ int32_t height, 32 | _In_ uint32_t capacity, 33 | _In_ uint32_t texturesPerAtlas, 34 | _In_ ID3D11Device* device, 35 | _In_ const std::shared_ptr& simd); 36 | 37 | virtual ~TextureCache() noexcept {} 38 | 39 | virtual void OnNewFrame() override; 40 | 41 | virtual TextureCacheLocation FindTexture( 42 | _In_ uint32_t contentKey, 43 | _In_ int32_t lastIndex) override; 44 | 45 | virtual TextureCacheLocation InsertTexture( 46 | _In_ uint32_t contentKey, 47 | _In_ const Batch& batch, 48 | _In_reads_(tmuDataSize) const uint8_t* tmuData, 49 | _In_ uint32_t tmuDataSize) override; 50 | 51 | virtual ID3D11ShaderResourceView* GetSrv( 52 | _In_ uint32_t atlasIndex) const override; 53 | 54 | virtual uint32_t GetMemoryFootprint() const override; 55 | 56 | virtual uint32_t GetUsedCount() const override; 57 | 58 | private: 59 | void CopyPixels( 60 | _In_ int32_t srcWidth, 61 | _In_ int32_t srcHeight, 62 | _In_reads_(srcPitch* srcHeight) const uint8_t* __restrict srcPixels, 63 | _In_ uint32_t srcPitch, 64 | _Out_writes_all_(dstPitch* srcHeight) uint8_t* __restrict dstPixels, 65 | _In_ uint32_t dstPitch); 66 | 67 | int32_t _width = 0; 68 | int32_t _height = 0; 69 | uint32_t _capacity = 0; 70 | uint32_t _texturesPerAtlas = 0; 71 | int32_t _atlasCount = 0; 72 | ComPtr _deviceContext; 73 | ComPtr _textures[4]; 74 | ComPtr _srvs[4]; 75 | TextureCachePolicyBitPmru _policy; 76 | }; 77 | } 78 | -------------------------------------------------------------------------------- /src/d2dx/TextureCachePolicyBitPmru.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "Utils.h" 21 | #include "TextureCachePolicyBitPmru.h" 22 | #include "ISimd.h" 23 | 24 | using namespace d2dx; 25 | 26 | _Use_decl_annotations_ 27 | TextureCachePolicyBitPmru::TextureCachePolicyBitPmru( 28 | uint32_t capacity, 29 | const std::shared_ptr& simd) : 30 | _capacity{ capacity }, 31 | _contentKeys{ capacity, true }, 32 | _usedInFrameBits{ capacity >> 5, true }, 33 | _mruBits{ capacity >> 5, true }, 34 | _simd{ simd } 35 | { 36 | assert(!(capacity & 63)); 37 | assert(simd); 38 | } 39 | 40 | _Use_decl_annotations_ 41 | int32_t TextureCachePolicyBitPmru::Find( 42 | uint32_t contentKey, 43 | int32_t lastIndex) 44 | { 45 | assert(contentKey != 0); 46 | 47 | if (_capacity == 0) 48 | { 49 | return -1; 50 | } 51 | 52 | if (lastIndex >= 0 && lastIndex < (int32_t)_capacity && 53 | contentKey == _contentKeys.items[lastIndex]) 54 | { 55 | _usedInFrameBits.items[lastIndex >> 5] |= 1 << (lastIndex & 31); 56 | _mruBits.items[lastIndex >> 5] |= 1 << (lastIndex & 31); 57 | return lastIndex; 58 | } 59 | 60 | int32_t findIndex = _simd->IndexOfUInt32(_contentKeys.items, _capacity, contentKey); 61 | 62 | if (findIndex >= 0) 63 | { 64 | _usedInFrameBits.items[findIndex >> 5] |= 1 << (findIndex & 31); 65 | _mruBits.items[findIndex >> 5] |= 1 << (findIndex & 31); 66 | return findIndex; 67 | } 68 | 69 | return -1; 70 | } 71 | 72 | _Use_decl_annotations_ 73 | int32_t TextureCachePolicyBitPmru::Insert( 74 | uint32_t contentKey, 75 | bool& evicted) 76 | { 77 | if (_capacity == 0) 78 | { 79 | evicted = false; 80 | return -1; 81 | } 82 | 83 | int32_t replacementIndex = -1; 84 | 85 | for (uint32_t i = 0; i < _mruBits.capacity; ++i) 86 | { 87 | DWORD ri; 88 | if (BitScanForward(&ri, (DWORD)~_mruBits.items[i])) 89 | { 90 | replacementIndex = (int32_t)(i * 32 + ri); 91 | break; 92 | } 93 | } 94 | 95 | if (replacementIndex < 0) 96 | { 97 | memcpy(_mruBits.items, _usedInFrameBits.items, sizeof(uint32_t) * _mruBits.capacity); 98 | 99 | for (uint32_t i = 0; i < _mruBits.capacity; ++i) 100 | { 101 | DWORD ri; 102 | if (BitScanForward(&ri, (DWORD)~_mruBits.items[i])) 103 | { 104 | replacementIndex = (int32_t)(i * 32 + ri); 105 | break; 106 | } 107 | } 108 | } 109 | 110 | if (replacementIndex < 0) 111 | { 112 | D2DX_LOG("All texture atlas entries used in a single frame, starting over!"); 113 | memset(_mruBits.items, 0, sizeof(uint32_t) * _mruBits.capacity); 114 | memset(_usedInFrameBits.items, 0, sizeof(uint32_t) * _usedInFrameBits.capacity); 115 | 116 | for (uint32_t i = 0; i < _mruBits.capacity; ++i) 117 | { 118 | DWORD ri; 119 | if (BitScanForward(&ri, (DWORD)~_mruBits.items[i])) 120 | { 121 | replacementIndex = (int32_t)(i * 32 + ri); 122 | break; 123 | } 124 | } 125 | } 126 | 127 | _mruBits.items[replacementIndex >> 5] |= 1 << (replacementIndex & 31); 128 | _usedInFrameBits.items[replacementIndex >> 5] |= 1 << (replacementIndex & 31); 129 | 130 | evicted = _contentKeys.items[replacementIndex] != 0; 131 | 132 | if (!evicted) 133 | { 134 | ++_usedCount; 135 | } 136 | 137 | _contentKeys.items[replacementIndex] = contentKey; 138 | 139 | return replacementIndex; 140 | } 141 | 142 | void TextureCachePolicyBitPmru::OnNewFrame() 143 | { 144 | memset(_usedInFrameBits.items, 0, sizeof(uint32_t) * _usedInFrameBits.capacity); 145 | } 146 | 147 | uint32_t TextureCachePolicyBitPmru::GetUsedCount() const 148 | { 149 | return _usedCount; 150 | } 151 | -------------------------------------------------------------------------------- /src/d2dx/TextureCachePolicyBitPmru.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Buffer.h" 22 | #include "ISimd.h" 23 | 24 | namespace d2dx 25 | { 26 | class TextureCachePolicyBitPmru final 27 | { 28 | public: 29 | TextureCachePolicyBitPmru() = default; 30 | TextureCachePolicyBitPmru& operator=(TextureCachePolicyBitPmru&& rhs) = default; 31 | 32 | TextureCachePolicyBitPmru( 33 | _In_ uint32_t capacity, 34 | _In_ const std::shared_ptr& simd); 35 | ~TextureCachePolicyBitPmru() noexcept {} 36 | 37 | int32_t Find( 38 | _In_ uint32_t contentKey, 39 | _In_ int32_t lastIndex); 40 | 41 | int32_t Insert( 42 | _In_ uint32_t contentKey, 43 | _Out_ bool& evicted); 44 | 45 | void OnNewFrame(); 46 | 47 | uint32_t GetUsedCount() const; 48 | 49 | private: 50 | uint32_t _capacity = 0; 51 | std::shared_ptr _simd; 52 | Buffer _contentKeys; 53 | Buffer _usedInFrameBits; 54 | Buffer _mruBits; 55 | uint32_t _usedCount = 0; 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /src/d2dx/TextureHasher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "TextureHasher.h" 21 | #include "Types.h" 22 | #include "Utils.h" 23 | 24 | using namespace d2dx; 25 | 26 | TextureHasher::TextureHasher() : 27 | _cache{ D2DX_TMU_MEMORY_SIZE / 256, true }, 28 | _cacheHits{ 0 }, 29 | _cacheMisses{ 0 } 30 | { 31 | } 32 | 33 | _Use_decl_annotations_ 34 | void TextureHasher::Invalidate( 35 | uint32_t startAddress) 36 | { 37 | _cache.items[startAddress >> 8] = 0; 38 | } 39 | 40 | _Use_decl_annotations_ 41 | uint32_t TextureHasher::GetHash( 42 | uint32_t startAddress, 43 | const uint8_t* pixels, 44 | uint32_t pixelsSize) 45 | { 46 | assert((startAddress & 255) == 0); 47 | 48 | uint32_t hash = _cache.items[startAddress >> 8]; 49 | 50 | if (hash) 51 | { 52 | ++_cacheHits; 53 | } 54 | else 55 | { 56 | ++_cacheMisses; 57 | hash = fnv_32a_buf((void*)pixels, pixelsSize, FNV1_32A_INIT); 58 | _cache.items[startAddress >> 8] = hash; 59 | } 60 | 61 | return hash; 62 | } 63 | 64 | void TextureHasher::PrintStats() 65 | { 66 | D2DX_DEBUG_LOG("Texture hash cache hits: %u (%i%%) misses %u", 67 | _cacheHits, 68 | (int32_t)(100.0f * (float)_cacheHits / (_cacheHits + _cacheMisses)), 69 | _cacheMisses 70 | ); 71 | } -------------------------------------------------------------------------------- /src/d2dx/TextureHasher.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "Buffer.h" 22 | 23 | namespace d2dx 24 | { 25 | class TextureHasher final 26 | { 27 | public: 28 | TextureHasher(); 29 | ~TextureHasher() noexcept {} 30 | 31 | void Invalidate( 32 | _In_ uint32_t startAddress); 33 | 34 | uint32_t GetHash( 35 | _In_ uint32_t startAddress, 36 | _In_reads_(pixelsSize) const uint8_t* pixels, 37 | _In_ uint32_t pixelsSize); 38 | 39 | void PrintStats(); 40 | 41 | private: 42 | Buffer _cache; 43 | uint32_t _cacheHits; 44 | uint32_t _cacheMisses; 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /src/d2dx/UnitMotionPredictor.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IGameHelper.h" 22 | #include "IRenderContext.h" 23 | 24 | namespace d2dx 25 | { 26 | class UnitMotionPredictor final 27 | { 28 | public: 29 | UnitMotionPredictor( 30 | _In_ const std::shared_ptr& gameHelper); 31 | 32 | void Update( 33 | _In_ IRenderContext* renderContext); 34 | 35 | Offset GetOffset( 36 | _In_ const D2::UnitAny* unit); 37 | 38 | void SetUnitScreenPos( 39 | _In_ const D2::UnitAny* unit, 40 | _In_ int32_t x, 41 | _In_ int32_t y); 42 | 43 | Offset GetOffsetForShadow( 44 | _In_ int32_t x, 45 | _In_ int32_t y); 46 | 47 | private: 48 | struct UnitIdAndType final 49 | { 50 | uint16_t unitType = 0; 51 | uint16_t unitId = 0; 52 | }; 53 | 54 | struct UnitMotion final 55 | { 56 | Offset GetOffset() const; 57 | 58 | uint32_t lastUsedFrame = 0; 59 | Offset lastPos = { 0, 0 }; 60 | Offset velocity = { 0, 0 }; 61 | Offset predictedPos = { 0, 0 }; 62 | Offset correctedPos = { 0, 0 }; 63 | int64_t dtLastPosChange = 0; 64 | }; 65 | 66 | std::shared_ptr _gameHelper; 67 | uint32_t _frame = 0; 68 | Buffer _unitIdAndTypes; 69 | Buffer _unitMotions; 70 | Buffer _unitScreenPositions; 71 | int32_t _unitsCount = 0; 72 | }; 73 | } 74 | -------------------------------------------------------------------------------- /src/d2dx/Utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "ErrorHandling.h" 22 | #include "Buffer.h" 23 | 24 | namespace d2dx 25 | { 26 | namespace detail 27 | { 28 | __declspec(noinline) void Log(_In_z_ const char* s); 29 | } 30 | 31 | int64_t TimeStart(); 32 | float TimeEndMs(int64_t start); 33 | 34 | 35 | #ifdef NDEBUG 36 | #define D2DX_DEBUG_LOG(fmt, ...) 37 | #else 38 | #define D2DX_DEBUG_LOG(fmt, ...) \ 39 | { \ 40 | static char ss[256]; \ 41 | sprintf_s(ss, fmt "\n", __VA_ARGS__); \ 42 | d2dx::detail::Log(ss); \ 43 | } 44 | #endif 45 | 46 | #define D2DX_LOG(fmt, ...) \ 47 | { \ 48 | static char ssss[256]; \ 49 | sprintf_s(ssss, fmt "\n", __VA_ARGS__); \ 50 | d2dx::detail::Log(ssss); \ 51 | } 52 | 53 | struct WindowsVersion 54 | { 55 | uint32_t major; 56 | uint32_t minor; 57 | uint32_t build; 58 | }; 59 | 60 | WindowsVersion GetWindowsVersion(); 61 | 62 | WindowsVersion GetActualWindowsVersion(); 63 | 64 | Buffer ReadTextFile( 65 | _In_z_ const char* filename); 66 | 67 | void DumpTexture( 68 | _In_ uint32_t hash, 69 | _In_ int32_t w, 70 | _In_ int32_t h, 71 | _In_reads_(pixelsSize) const uint8_t* pixels, 72 | _In_ uint32_t pixelsSize, 73 | _In_ uint32_t textureCategory, 74 | _In_reads_(256) const uint32_t* palette); 75 | 76 | bool DecompressLZMAToFile( 77 | _In_reads_(dataSize) const uint8_t* data, 78 | _In_ uint32_t dataSize, 79 | _In_z_ const char* filename); 80 | } 81 | -------------------------------------------------------------------------------- /src/d2dx/Vertex.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | namespace d2dx 22 | { 23 | class Vertex final 24 | { 25 | public: 26 | Vertex() noexcept : 27 | _x{ 0 }, 28 | _y{ 0 }, 29 | _s{ 0 }, 30 | _t{ 0 }, 31 | _color{ 0 }, 32 | _isChromaKeyEnabled_surfaceId{ 0 }, 33 | _paletteIndex_atlasIndex{ 0 } 34 | { 35 | } 36 | 37 | Vertex( 38 | int32_t x, 39 | int32_t y, 40 | int32_t s, 41 | int32_t t, 42 | uint32_t color, 43 | bool isChromaKeyEnabled, 44 | int32_t atlasIndex, 45 | int32_t paletteIndex, 46 | int32_t surfaceId) noexcept : 47 | _x(x), 48 | _y(y), 49 | _s(s), 50 | _t(t), 51 | _color(color), 52 | _isChromaKeyEnabled_surfaceId((isChromaKeyEnabled ? 0x4000 : 0) | (surfaceId & 16383)), 53 | _paletteIndex_atlasIndex((paletteIndex << 12) | (atlasIndex & 4095)) 54 | { 55 | assert(x >= INT16_MIN && x <= INT16_MAX); 56 | assert(y >= INT16_MIN && y <= INT16_MAX); 57 | assert(s >= INT16_MIN && s <= INT16_MAX); 58 | assert(t >= INT16_MIN && t <= INT16_MAX); 59 | assert(paletteIndex >= 0 && paletteIndex < D2DX_MAX_PALETTES); 60 | assert(atlasIndex >= 0 && atlasIndex <= 4095); 61 | assert(surfaceId >= 0 && surfaceId <= 16383); 62 | } 63 | 64 | inline void AddOffset( 65 | _In_ int32_t x, 66 | _In_ int32_t y) noexcept 67 | { 68 | _x += x; 69 | _y += y; 70 | } 71 | 72 | inline int32_t GetX() const noexcept 73 | { 74 | return _x; 75 | } 76 | 77 | inline int32_t GetY() const noexcept 78 | { 79 | return _y; 80 | } 81 | 82 | inline void SetPosition(int32_t x, int32_t y) noexcept 83 | { 84 | _x = x; 85 | _y = y; 86 | } 87 | 88 | inline void SetSurfaceId(int32_t surfaceId) noexcept 89 | { 90 | assert(surfaceId >= 0 && surfaceId <= 16383); 91 | _isChromaKeyEnabled_surfaceId &= ~16383; 92 | _isChromaKeyEnabled_surfaceId |= surfaceId & 16383; 93 | } 94 | 95 | inline int32_t GetSurfaceId() const noexcept 96 | { 97 | return _isChromaKeyEnabled_surfaceId & 16383; 98 | } 99 | 100 | inline int32_t GetS() const noexcept 101 | { 102 | return _s; 103 | } 104 | 105 | inline int32_t GetT() const noexcept 106 | { 107 | return _t; 108 | } 109 | 110 | inline void SetTexcoord(int32_t s, int32_t t) noexcept 111 | { 112 | assert(s >= 0 && s <= 511); 113 | assert(t >= 0 && t <= 511); 114 | _s = s; 115 | _t = t; 116 | } 117 | 118 | inline uint32_t GetColor() const noexcept 119 | { 120 | return _color; 121 | } 122 | 123 | inline void SetColor(uint32_t color) noexcept 124 | { 125 | _color = color; 126 | } 127 | 128 | inline bool IsChromaKeyEnabled() const noexcept 129 | { 130 | return (_isChromaKeyEnabled_surfaceId & 0x4000) != 0; 131 | } 132 | 133 | private: 134 | int16_t _x; 135 | int16_t _y; 136 | int16_t _s; 137 | int16_t _t; 138 | uint32_t _color; 139 | uint16_t _paletteIndex_atlasIndex; 140 | uint16_t _isChromaKeyEnabled_surfaceId; 141 | }; 142 | 143 | static_assert(sizeof(Vertex) == 16, "sizeof(Vertex)"); 144 | } 145 | -------------------------------------------------------------------------------- /src/d2dx/VideoPS.hlsl: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "Constants.hlsli" 20 | #include "Display.hlsli" 21 | 22 | Texture2D tex : register(t0); 23 | 24 | float4 main( 25 | in DisplayPSInput ps_in) : SV_TARGET 26 | { 27 | return tex.Sample(BilinearSampler, ps_in.tc) * float4(1, 1, 1, 0) + float4(0, 0, 0, 1); 28 | } 29 | -------------------------------------------------------------------------------- /src/d2dx/WeatherMotionPredictor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "WeatherMotionPredictor.h" 21 | 22 | using namespace d2dx; 23 | using namespace DirectX; 24 | 25 | _Use_decl_annotations_ 26 | WeatherMotionPredictor::WeatherMotionPredictor( 27 | const std::shared_ptr& gameHelper) : 28 | _gameHelper{ gameHelper }, 29 | _particleMotions{ 512, true } 30 | { 31 | } 32 | 33 | _Use_decl_annotations_ 34 | void WeatherMotionPredictor::Update( 35 | IRenderContext* renderContext) 36 | { 37 | _dt = _gameHelper->IsGameMenuOpen() ? 0.0f : renderContext->GetFrameTime(); 38 | ++_frame; 39 | } 40 | 41 | _Use_decl_annotations_ 42 | OffsetF WeatherMotionPredictor::GetOffset( 43 | int32_t particleIndex, 44 | OffsetF posFromGame) 45 | { 46 | ParticleMotion& pm = _particleMotions.items[particleIndex & 511]; 47 | 48 | const OffsetF diff = posFromGame - pm.lastPos; 49 | const float error = max(abs(diff.x), abs(diff.y)); 50 | 51 | if (abs(_frame - pm.lastUsedFrame) > 2 || 52 | error > 100.0f) 53 | { 54 | pm.velocity = { 0.0f, 0.0f }; 55 | pm.lastPos = posFromGame; 56 | pm.predictedPos = pm.lastPos; 57 | } 58 | else 59 | { 60 | if (error > 0.0f) 61 | { 62 | pm.velocity = diff * 25.0f; 63 | pm.lastPos = posFromGame; 64 | } 65 | } 66 | 67 | pm.predictedPos += pm.velocity * _dt; 68 | pm.lastUsedFrame = _frame; 69 | 70 | return pm.predictedPos - pm.lastPos; 71 | } 72 | -------------------------------------------------------------------------------- /src/d2dx/WeatherMotionPredictor.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #pragma once 20 | 21 | #include "IGameHelper.h" 22 | #include "IRenderContext.h" 23 | 24 | namespace d2dx 25 | { 26 | #pragma once 27 | class WeatherMotionPredictor 28 | { 29 | public: 30 | WeatherMotionPredictor( 31 | _In_ const std::shared_ptr& gameHelper); 32 | 33 | void Update( 34 | _In_ IRenderContext* renderContext); 35 | 36 | OffsetF GetOffset( 37 | _In_ int32_t particleIndex, 38 | _In_ OffsetF posFromGame); 39 | 40 | private: 41 | struct ParticleMotion final 42 | { 43 | OffsetF lastPos = { 0, 0 }; 44 | OffsetF velocity = { 0, 0 }; 45 | OffsetF predictedPos = { 0, 0 }; 46 | int32_t lastUsedFrame = 0; 47 | }; 48 | 49 | std::shared_ptr _gameHelper; 50 | int32_t _frame = 0; 51 | float _dt = 0; 52 | Buffer _particleMotions; 53 | }; 54 | } 55 | -------------------------------------------------------------------------------- /src/d2dx/d2dx.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "winres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // Swedish (Sweden) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SVE) 19 | LANGUAGE LANG_SWEDISH, SUBLANG_SWEDISH 20 | #pragma code_page(1252) 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Version 51 | // 52 | 53 | VS_VERSION_INFO VERSIONINFO 54 | FILEVERSION 0,99,330,0 55 | PRODUCTVERSION 0,99,330,0 56 | FILEFLAGSMASK 0x3fL 57 | #ifdef _DEBUG 58 | FILEFLAGS 0x1L 59 | #else 60 | FILEFLAGS 0x0L 61 | #endif 62 | FILEOS 0x40004L 63 | FILETYPE 0x2L 64 | FILESUBTYPE 0x0L 65 | BEGIN 66 | BLOCK "StringFileInfo" 67 | BEGIN 68 | BLOCK "041d04b0" 69 | BEGIN 70 | VALUE "CompanyName", "Bolrog" 71 | VALUE "FileDescription", "Glide wrapper for D2" 72 | VALUE "FileVersion", "0.99.529.0" 73 | VALUE "InternalName", "d2dx.dll" 74 | VALUE "LegalCopyright", "Copyright (C) 2021" 75 | VALUE "OriginalFilename", "d2dx.dll" 76 | VALUE "ProductName", "D2DX" 77 | VALUE "ProductVersion", "0.99.529.0" 78 | END 79 | END 80 | BLOCK "VarFileInfo" 81 | BEGIN 82 | VALUE "Translation", 0x41d, 1200 83 | END 84 | END 85 | 86 | 87 | ///////////////////////////////////////////////////////////////////////////// 88 | // 89 | // mpq 90 | // 91 | 92 | IDR_SGD2FR_MPQ mpq "..\\..\\thirdparty\\sgd2freeres\\sgd2freeres.mpq.lzma" 93 | IDR_SGD2FR_DLL dll "..\\..\\thirdparty\\sgd2freeres\\sgd2freeres.dll.lzma" 94 | 95 | #endif // Swedish (Sweden) resources 96 | ///////////////////////////////////////////////////////////////////////////// 97 | 98 | 99 | 100 | #ifndef APSTUDIO_INVOKED 101 | ///////////////////////////////////////////////////////////////////////////// 102 | // 103 | // Generated from the TEXTINCLUDE 3 resource. 104 | // 105 | 106 | 107 | ///////////////////////////////////////////////////////////////////////////// 108 | #endif // not APSTUDIO_INVOKED 109 | 110 | -------------------------------------------------------------------------------- /src/d2dx/d2dx.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | C:\games\Diablo II\Game.exe 5 | WindowsLocalDebugger 6 | -ns -3dfx -w -dxtestsleepfix 7 | C:\games\Diablo II\ 8 | NativeOnly 9 | 10 | 11 | C:\games\Diablo II\game.exe 12 | WindowsLocalDebugger 13 | -3dfx -ns -w -dxnoclipcursor -dxtestsleepfix 14 | C:\games\Diablo II\ 15 | NativeOnly 16 | 17 | -------------------------------------------------------------------------------- /src/d2dx/dllmain.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include "Detours.h" 21 | 22 | #pragma comment(lib, "comctl32.lib") 23 | #pragma comment(lib, "dxgi.lib") 24 | #pragma comment(lib, "d3d11.lib") 25 | #pragma comment(lib, "d3dcompiler.lib") 26 | 27 | using namespace d2dx; 28 | using namespace std; 29 | 30 | BOOL APIENTRY DllMain( 31 | _In_ HMODULE hModule, 32 | _In_ DWORD ul_reason_for_call, 33 | _In_ LPVOID lpReserved 34 | ) 35 | { 36 | switch (ul_reason_for_call) 37 | { 38 | case DLL_PROCESS_ATTACH: 39 | SetProcessDPIAware(); 40 | AttachDetours(); 41 | break; 42 | case DLL_THREAD_ATTACH: 43 | break; 44 | case DLL_THREAD_DETACH: 45 | break; 46 | case DLL_PROCESS_DETACH: 47 | DetachDetours(); 48 | break; 49 | } 50 | return TRUE; 51 | } 52 | -------------------------------------------------------------------------------- /src/d2dx/pch.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | -------------------------------------------------------------------------------- /src/d2dx/pch.h: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #ifndef PCH_H 20 | #define PCH_H 21 | 22 | #define WIN32_LEAN_AND_MEAN 23 | #define __MSC__ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | 45 | #include "../../thirdparty/fnv/fnv.h" 46 | #include "../../thirdparty/detours/detours.h" 47 | #include 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | template 59 | using ComPtr = Microsoft::WRL::ComPtr; 60 | 61 | using EventHandle = Microsoft::WRL::Wrappers::HandleT; 62 | 63 | #endif //PCH_H 64 | -------------------------------------------------------------------------------- /src/d2dx/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by d2dx.rc 4 | // 5 | #define IDR_SGD2FR_MPQ 101 6 | #define IDR_SGD2FR_DLL 102 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 102 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/d2dxtests/TestMetrics.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include 21 | #include "CppUnitTest.h" 22 | #include "../d2dx/Metrics.h" 23 | 24 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 25 | using namespace d2dx; 26 | using namespace DirectX; 27 | 28 | namespace Microsoft 29 | { 30 | namespace VisualStudio 31 | { 32 | namespace CppUnitTestFramework 33 | { 34 | template<> static std::wstring ToString(const Offset& t) { return ToString(t.x) + L", " + ToString(t.y); } 35 | template<> static std::wstring ToString(const Size& t) { return ToString(t.width) + L"x" + ToString(t.height); } 36 | } 37 | } 38 | } 39 | 40 | namespace d2dxtests 41 | { 42 | TEST_CLASS(TestStandardMetrics) 43 | { 44 | public: 45 | TEST_METHOD(TestGetStandardDesktopSizes) 46 | { 47 | auto standardDesktopSizes = d2dx::Metrics::GetStandardDesktopSizes(); 48 | Assert::IsTrue(standardDesktopSizes.capacity > 8); 49 | } 50 | 51 | TEST_METHOD(TestGetGameSize) 52 | { 53 | auto suggestedGameSize = d2dx::Metrics::GetSuggestedGameSize({ 1920, 1080 }, false); 54 | Assert::AreEqual(Size(720, 540), suggestedGameSize); 55 | 56 | // Odd desktop size that isn't large enough to divide down. 57 | suggestedGameSize = d2dx::Metrics::GetSuggestedGameSize({ 1000, 500 }, true); 58 | Assert::AreEqual(Size(1000, 500), suggestedGameSize); 59 | 60 | // Odd desktop size where a 2x integer scale would result in a too small game size. 61 | suggestedGameSize = d2dx::Metrics::GetSuggestedGameSize({ 2001, 1003 }, true); 62 | Assert::AreEqual(Size(1436, 720), suggestedGameSize); 63 | } 64 | 65 | void AssertThatGameSizeIsIntegerScale(Size desktopSize, bool wide, bool lenient) 66 | { 67 | auto suggestedGameSize = d2dx::Metrics::GetSuggestedGameSize(desktopSize, wide); 68 | auto renderRect = d2dx::Metrics::GetRenderRect(suggestedGameSize, desktopSize, wide); 69 | Assert::IsTrue(renderRect.offset.x >= 0); 70 | Assert::IsTrue(renderRect.offset.y >= 0); 71 | Assert::IsTrue(renderRect.size.width > 0); 72 | Assert::IsTrue(renderRect.size.height > 0); 73 | Assert::IsTrue((renderRect.offset.x + renderRect.size.width) <= desktopSize.width); 74 | Assert::IsTrue((renderRect.offset.y + renderRect.size.height) <= desktopSize.height); 75 | 76 | if (renderRect.offset.x > 0 && renderRect.offset.y > 0) 77 | { 78 | Assert::IsTrue(renderRect.offset.x < 16 || renderRect.offset.y < 16); 79 | } 80 | 81 | int32_t reconstructedDesktopWidth = renderRect.size.width + renderRect.offset.x * 2; 82 | int32_t reconstructedDesktopHeight = renderRect.size.height + renderRect.offset.y * 2; 83 | 84 | if (lenient) 85 | { 86 | /* The "remainder" on the right may not be exactly equal to desktop width. */ 87 | Assert::IsTrue(desktopSize.width == reconstructedDesktopWidth || desktopSize.width == reconstructedDesktopWidth + 1); 88 | 89 | /* The "remainder" on the bottom may not be exactly equal to desktop height. */ 90 | Assert::IsTrue(desktopSize.height == reconstructedDesktopHeight || desktopSize.height == reconstructedDesktopHeight + 1); 91 | } 92 | else 93 | { 94 | Assert::AreEqual(desktopSize.width, reconstructedDesktopWidth); 95 | Assert::AreEqual(desktopSize.height, reconstructedDesktopHeight); 96 | } 97 | } 98 | 99 | TEST_METHOD(TestRenderRectsAreGoodForStandardDesktopSizes) 100 | { 101 | auto standardDesktopSizes = d2dx::Metrics::GetStandardDesktopSizes(); 102 | for (uint32_t i = 0; i < standardDesktopSizes.capacity; ++i) 103 | { 104 | AssertThatGameSizeIsIntegerScale(standardDesktopSizes.items[i], false, false); 105 | AssertThatGameSizeIsIntegerScale(standardDesktopSizes.items[i], true, false); 106 | } 107 | } 108 | 109 | TEST_METHOD(TestRenderRectsAreGoodForNonStandardDesktopSizes) 110 | { 111 | for (int32_t width = 50; width < 1600; ++width) 112 | { 113 | AssertThatGameSizeIsIntegerScale({ width, 503 }, false, true); 114 | AssertThatGameSizeIsIntegerScale({ width, 503 }, true, true); 115 | } 116 | for (int32_t height = 50; height < 1600; ++height) 117 | { 118 | AssertThatGameSizeIsIntegerScale({ 614, height }, false, true); 119 | AssertThatGameSizeIsIntegerScale({ 614, height }, true, true); 120 | } 121 | } 122 | }; 123 | } 124 | -------------------------------------------------------------------------------- /src/d2dxtests/TestSimd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include 21 | #include "CppUnitTest.h" 22 | #include "../d2dx/SimdSse2.h" 23 | 24 | using namespace Microsoft::WRL; 25 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 26 | using namespace d2dx; 27 | 28 | namespace d2dxtests 29 | { 30 | TEST_CLASS(TestSimd) 31 | { 32 | public: 33 | TEST_METHOD(Create) 34 | { 35 | auto simd = std::make_shared(); 36 | } 37 | 38 | TEST_METHOD(FindUInt32) 39 | { 40 | auto simd = std::make_shared(); 41 | 42 | alignas(64) std::array items; 43 | 44 | for (int32_t i = 0; i < 1024; ++i) 45 | { 46 | items[i] = 1023 - i; 47 | } 48 | 49 | Assert::AreEqual(0, simd->IndexOfUInt32(items.data(), items.size(), 1023)); 50 | Assert::AreEqual(1023, simd->IndexOfUInt32(items.data(), items.size(), 0)); 51 | Assert::AreEqual(1009, simd->IndexOfUInt32(items.data(), items.size(), 14)); 52 | Assert::AreEqual(114, simd->IndexOfUInt32(items.data(), items.size(), 909)); 53 | } 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /src/d2dxtests/TestTextureCache.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | #include "pch.h" 20 | #include 21 | #include "CppUnitTest.h" 22 | 23 | #include "../d2dx/Batch.h" 24 | #include "../d2dx/SimdSse2.h" 25 | #include "../d2dx/Types.h" 26 | #include "../d2dx/TextureCache.h" 27 | 28 | using namespace Microsoft::VisualStudio::CppUnitTestFramework; 29 | using namespace d2dx; 30 | 31 | namespace d2dxtests 32 | { 33 | TEST_CLASS(TestTextureCache) 34 | { 35 | public: 36 | TEST_METHOD(CreateAtlas) 37 | { 38 | auto simd = std::make_shared(); 39 | for (int32_t h = 3; h <= 8; ++h) 40 | { 41 | for (int32_t w = 3; w <= 8; ++w) 42 | { 43 | auto textureCache = std::make_unique( 44 | 1 << w, 1 << h, 1024, 512, (ID3D11Device*)nullptr, simd); 45 | } 46 | } 47 | } 48 | 49 | TEST_METHOD(FindNonExistentTexture) 50 | { 51 | auto simd = std::make_shared(); 52 | auto textureCache = std::make_unique(256, 128, 2048, 512, (ID3D11Device*)nullptr, simd); 53 | auto tcl = textureCache->FindTexture(0x12345678, -1); 54 | Assert::AreEqual((int16_t)-1, tcl._textureAtlas); 55 | Assert::AreEqual((int16_t)-1, tcl._textureIndex); 56 | } 57 | 58 | TEST_METHOD(InsertAndFindTextures) 59 | { 60 | auto simd = std::make_shared(); 61 | std::array tmuData; 62 | 63 | Batch batch; 64 | batch.SetTextureStartAddress(0); 65 | batch.SetTextureSize(256, 128); 66 | 67 | auto textureCache = std::make_unique(256, 128, 64, 512, (ID3D11Device*)nullptr, simd); 68 | 69 | for (uint32_t i = 0; i < 64; ++i) 70 | { 71 | uint32_t hash = (0xFF << 24) | (i << 16) | (i << 8) | i; 72 | textureCache->InsertTexture(hash, batch, (const uint8_t*)tmuData.data(), (uint32_t)tmuData.size()); 73 | } 74 | 75 | for (uint32_t i = 0; i < 64; ++i) 76 | { 77 | uint32_t hash = (0xFF << 24) | (i << 16) | (i << 8) | i; 78 | auto tcl = textureCache->FindTexture(hash, -1); 79 | Assert::AreEqual((int16_t)0, tcl._textureAtlas); 80 | Assert::AreEqual((int16_t)i, tcl._textureIndex); 81 | } 82 | } 83 | 84 | TEST_METHOD(FirstInsertedTextureIsReplaced) 85 | { 86 | auto simd = std::make_shared(); 87 | std::array tmuData; 88 | 89 | Batch batch; 90 | batch.SetTextureStartAddress(0); 91 | batch.SetTextureSize(256, 128); 92 | 93 | auto textureCache = std::make_unique(256, 128, 64, 512, (ID3D11Device*)nullptr, simd); 94 | 95 | for (uint32_t i = 0; i < 65; ++i) 96 | { 97 | uint32_t hash = (0xFF << 24) | (i << 16) | (i << 8) | i; 98 | auto tcl = textureCache->InsertTexture(hash, batch, (const uint8_t*)tmuData.data(), (uint32_t)tmuData.size()); 99 | 100 | if (i == 64) 101 | { 102 | Assert::AreEqual((int16_t)0, tcl._textureAtlas); 103 | Assert::AreEqual((int16_t)0, tcl._textureIndex); 104 | } 105 | else 106 | { 107 | Assert::AreEqual((int16_t)0, tcl._textureAtlas); 108 | Assert::AreEqual((int16_t)i, tcl._textureIndex); 109 | } 110 | } 111 | 112 | for (uint32_t i = 0; i < 64; ++i) 113 | { 114 | uint32_t hash = (0xFF << 24) | (i << 16) | (i << 8) | i; 115 | auto tcl = textureCache->FindTexture(hash, -1); 116 | 117 | int16_t expectedTextureAtlas = 0; 118 | int16_t expectedTextureIndex = i; 119 | 120 | if (i == 0) 121 | { 122 | expectedTextureAtlas = -1; 123 | expectedTextureIndex = -1; 124 | } 125 | else if (i == 64) 126 | { 127 | expectedTextureIndex = 0; 128 | } 129 | 130 | Assert::AreEqual(expectedTextureAtlas, tcl._textureAtlas); 131 | Assert::AreEqual(expectedTextureIndex, tcl._textureIndex); 132 | } 133 | } 134 | 135 | TEST_METHOD(SecondInsertedTextureIsReplacedIfFirstOneWasUsedInFrame) 136 | { 137 | auto simd = std::make_shared(); 138 | std::array tmuData; 139 | 140 | Batch batch; 141 | batch.SetTextureStartAddress(0); 142 | batch.SetTextureSize(256, 128); 143 | 144 | auto textureCache = std::make_unique(256, 128, 64, 512, (ID3D11Device*)nullptr, simd); 145 | 146 | for (uint32_t i = 0; i < 65; ++i) 147 | { 148 | uint32_t hash = (0xFF << 24) | (i << 16) | (i << 8) | i; 149 | 150 | if (i == 64) 151 | { 152 | // Simulate new frame and use of texture in slot 0 153 | textureCache->OnNewFrame(); 154 | auto tcl = textureCache->FindTexture(0xFF000000, -1); 155 | Assert::AreEqual((int16_t)0, tcl._textureAtlas); 156 | Assert::AreEqual((int16_t)0, tcl._textureIndex); 157 | } 158 | 159 | auto tcl = textureCache->InsertTexture(hash, batch, (const uint8_t*)tmuData.data(), (uint32_t)tmuData.size()); 160 | 161 | if (i == 64) 162 | { 163 | Assert::AreEqual((int16_t)0, tcl._textureAtlas); 164 | Assert::AreEqual((int16_t)1, tcl._textureIndex); 165 | } 166 | else 167 | { 168 | Assert::AreEqual((int16_t)0, tcl._textureAtlas); 169 | Assert::AreEqual((int16_t)i, tcl._textureIndex); 170 | } 171 | } 172 | 173 | for (uint32_t i = 0; i < 64; ++i) 174 | { 175 | uint32_t hash = (0xFF << 24) | (i << 16) | (i << 8) | i; 176 | auto tcl = textureCache->FindTexture(hash, -1); 177 | 178 | int16_t expectedTextureAtlas = 0; 179 | int16_t expectedTextureIndex = i; 180 | 181 | if (i == 1) 182 | { 183 | expectedTextureAtlas = -1; 184 | expectedTextureIndex = -1; 185 | } 186 | else if (i == 64) 187 | { 188 | expectedTextureIndex = 1; 189 | } 190 | 191 | Assert::AreEqual(expectedTextureAtlas, tcl._textureAtlas); 192 | Assert::AreEqual(expectedTextureIndex, tcl._textureIndex); 193 | } 194 | } 195 | }; 196 | } 197 | -------------------------------------------------------------------------------- /src/d2dxtests/d2dxtests.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {0657af1f-16df-48e5-8bb7-323129c7f9a9} 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | d2dx 14 | 15 | 16 | d2dx 17 | 18 | 19 | d2dx 20 | 21 | 22 | d2dx 23 | 24 | 25 | d2dx 26 | 27 | 28 | 29 | d2dx 30 | 31 | 32 | 33 | 34 | 35 | d2dx 36 | 37 | 38 | d2dx 39 | 40 | 41 | d2dx 42 | 43 | 44 | d2dx 45 | 46 | 47 | d2dx 48 | 49 | 50 | d2dx 51 | 52 | 53 | d2dx 54 | 55 | 56 | d2dx 57 | 58 | 59 | d2dx 60 | 61 | 62 | d2dx 63 | 64 | 65 | d2dx 66 | 67 | 68 | d2dx 69 | 70 | 71 | d2dx 72 | 73 | 74 | d2dx 75 | 76 | 77 | -------------------------------------------------------------------------------- /src/d2dxtests/d2dxtests.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/d2dxtests/pch.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | This file is part of D2DX. 3 | 4 | Copyright (C) 2021 Bolrog 5 | 6 | D2DX is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | D2DX is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with D2DX. If not, see . 18 | */ 19 | 20 | #include "pch.h" 21 | -------------------------------------------------------------------------------- /thirdparty/detours/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/detours/detours.lib -------------------------------------------------------------------------------- /thirdparty/detours/detours.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/detours/detours.pdb -------------------------------------------------------------------------------- /thirdparty/detours/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY_(x) #x 18 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /thirdparty/detours/syelog.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Detours Test Program (syelog.h of syelog.lib) 4 | // 5 | // Microsoft Research Detours Package 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | #pragma once 10 | #ifndef _SYELOGD_H_ 11 | #define _SYELOGD_H_ 12 | #include 13 | 14 | #pragma pack(push, 1) 15 | #pragma warning(push) 16 | #pragma warning(disable: 4200) 17 | 18 | ////////////////////////////////////////////////////////////////////////////// 19 | // 20 | // 21 | #define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog" 22 | #define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog" 23 | #ifdef UNICODE 24 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW 25 | #else 26 | #define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA 27 | #endif 28 | 29 | ////////////////////////////////////////////////////////////////////////////// 30 | // 31 | #define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff) 32 | 33 | typedef struct _SYELOG_MESSAGE 34 | { 35 | USHORT nBytes; 36 | BYTE nFacility; 37 | BYTE nSeverity; 38 | DWORD nProcessId; 39 | FILETIME ftOccurance; 40 | BOOL fTerminate; 41 | CHAR szMessage[SYELOG_MAXIMUM_MESSAGE]; 42 | } SYELOG_MESSAGE, *PSYELOG_MESSAGE; 43 | 44 | 45 | // Facility Codes. 46 | // 47 | #define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel 48 | #define SYELOG_FACILITY_SECURITY 0x20 // OS Security 49 | #define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal 50 | #define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon 51 | #define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application 52 | #define SYELOG_FACILITY_USER 0x60 // User self-generated. 53 | #define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined. 54 | #define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined. 55 | #define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined. 56 | #define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined. 57 | #define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined. 58 | #define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined. 59 | #define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined. 60 | #define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined. 61 | #define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined. 62 | #define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined. 63 | 64 | // Severity Codes. 65 | // 66 | #define SYELOG_SEVERITY_FATAL 0x00 // System is dead. 67 | #define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately. 68 | #define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition. 69 | #define SYELOG_SEVERITY_ERROR 0x30 // Error 70 | #define SYELOG_SEVERITY_WARNING 0x40 // Warning 71 | #define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition. 72 | #define SYELOG_SEVERITY_INFORMATION 0x60 // Informational 73 | #define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed 74 | #define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded 75 | #define SYELOG_SEVERITY_DEBUG 0x70 // Debugging 76 | 77 | // Logging Functions. 78 | // 79 | VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility); 80 | VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...); 81 | VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args); 82 | VOID SyelogClose(BOOL fTerminate); 83 | 84 | #pragma warning(pop) 85 | #pragma pack(pop) 86 | 87 | #endif // _SYELOGD_H_ 88 | // 89 | ///////////////////////////////////////////////////////////////// End of File. 90 | -------------------------------------------------------------------------------- /thirdparty/detours/syelog.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/detours/syelog.lib -------------------------------------------------------------------------------- /thirdparty/fnv/fnv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fnv - Fowler/Noll/Vo- hash code 3 | * 4 | * @(#) $Revision: 5.4 $ 5 | * @(#) $Id: fnv.h,v 5.4 2009/07/30 22:49:13 chongo Exp $ 6 | * @(#) $Source: /usr/local/src/cmd/fnv/RCS/fnv.h,v $ 7 | * 8 | *** 9 | * 10 | * Fowler/Noll/Vo- hash 11 | * 12 | * The basis of this hash algorithm was taken from an idea sent 13 | * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 | * 15 | * Phong Vo (http://www.research.att.com/info/kpv/) 16 | * Glenn Fowler (http://www.research.att.com/~gsf/) 17 | * 18 | * In a subsequent ballot round: 19 | * 20 | * Landon Curt Noll (http://www.isthe.com/chongo/) 21 | * 22 | * improved on their algorithm. Some people tried this hash 23 | * and found that it worked rather well. In an EMail message 24 | * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 | * 26 | * FNV hashes are designed to be fast while maintaining a low 27 | * collision rate. The FNV speed allows one to quickly hash lots 28 | * of data while maintaining a reasonable collision rate. See: 29 | * 30 | * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 | * 32 | * for more details as well as other forms of the FNV hash. 33 | * 34 | *** 35 | * 36 | * NOTE: The FNV-0 historic hash is not recommended. One should use 37 | * the FNV-1 hash instead. 38 | * 39 | * To use the 32 bit FNV-0 historic hash, pass FNV0_32_INIT as the 40 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 41 | * 42 | * To use the 64 bit FNV-0 historic hash, pass FNV0_64_INIT as the 43 | * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 44 | * 45 | * To use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the 46 | * Fnv32_t hashval argument to fnv_32_buf() or fnv_32_str(). 47 | * 48 | * To use the recommended 64 bit FNV-1 hash, pass FNV1_64_INIT as the 49 | * Fnv64_t hashval argument to fnv_64_buf() or fnv_64_str(). 50 | * 51 | * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the 52 | * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). 53 | * 54 | * To use the recommended 64 bit FNV-1a hash, pass FNV1A_64_INIT as the 55 | * Fnv64_t hashval argument to fnv_64a_buf() or fnv_64a_str(). 56 | * 57 | *** 58 | * 59 | * Please do not copyright this code. This code is in the public domain. 60 | * 61 | * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 62 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 63 | * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 64 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 65 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 66 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 67 | * PERFORMANCE OF THIS SOFTWARE. 68 | * 69 | * By: 70 | * chongo /\oo/\ 71 | * http://www.isthe.com/chongo/ 72 | * 73 | * Share and Enjoy! :-) 74 | */ 75 | 76 | #if !defined(__FNV_H__) 77 | #define __FNV_H__ 78 | 79 | #include 80 | #include 81 | 82 | #define FNV_VERSION "5.0.2" /* @(#) FNV Version */ 83 | 84 | 85 | /* 86 | * 32 bit FNV-0 hash type 87 | */ 88 | typedef uint32_t Fnv32_t; 89 | 90 | /* 91 | * 32 bit FNV-1 and FNV-1a non-zero initial basis 92 | * 93 | * The FNV-1 initial basis is the FNV-0 hash of the following 32 octets: 94 | * 95 | * chongo /\../\ 96 | * 97 | * NOTE: The \'s above are not back-slashing escape characters. 98 | * They are literal ASCII backslash 0x5c characters. 99 | * 100 | * NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition. 101 | */ 102 | #define FNV1_32_INIT ((Fnv32_t)0x01000193) 103 | #define FNV1_32A_INIT FNV1_32_INIT 104 | 105 | /* 106 | * external functions 107 | */ 108 | 109 | /* hash_32a.c */ 110 | extern Fnv32_t fnv_32a_buf(void *buf, size_t len, Fnv32_t hashval); 111 | extern Fnv32_t fnv_32a_str(char *buf, Fnv32_t hashval); 112 | 113 | #endif /* __FNV_H__ */ 114 | -------------------------------------------------------------------------------- /thirdparty/fnv/hash_32a.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hash_32 - 32 bit Fowler/Noll/Vo FNV-1a hash code 3 | * 4 | * @(#) $Revision: 5.1 $ 5 | * @(#) $Id: hash_32a.c,v 5.1 2009/06/30 09:13:32 chongo Exp $ 6 | * @(#) $Source: /usr/local/src/cmd/fnv/RCS/hash_32a.c,v $ 7 | * 8 | *** 9 | * 10 | * Fowler/Noll/Vo hash 11 | * 12 | * The basis of this hash algorithm was taken from an idea sent 13 | * as reviewer comments to the IEEE POSIX P1003.2 committee by: 14 | * 15 | * Phong Vo (http://www.research.att.com/info/kpv/) 16 | * Glenn Fowler (http://www.research.att.com/~gsf/) 17 | * 18 | * In a subsequent ballot round: 19 | * 20 | * Landon Curt Noll (http://www.isthe.com/chongo/) 21 | * 22 | * improved on their algorithm. Some people tried this hash 23 | * and found that it worked rather well. In an EMail message 24 | * to Landon, they named it the ``Fowler/Noll/Vo'' or FNV hash. 25 | * 26 | * FNV hashes are designed to be fast while maintaining a low 27 | * collision rate. The FNV speed allows one to quickly hash lots 28 | * of data while maintaining a reasonable collision rate. See: 29 | * 30 | * http://www.isthe.com/chongo/tech/comp/fnv/index.html 31 | * 32 | * for more details as well as other forms of the FNV hash. 33 | *** 34 | * 35 | * To use the recommended 32 bit FNV-1a hash, pass FNV1_32A_INIT as the 36 | * Fnv32_t hashval argument to fnv_32a_buf() or fnv_32a_str(). 37 | * 38 | *** 39 | * 40 | * Please do not copyright this code. This code is in the public domain. 41 | * 42 | * LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 43 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 44 | * EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 45 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 46 | * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 47 | * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 48 | * PERFORMANCE OF THIS SOFTWARE. 49 | * 50 | * By: 51 | * chongo /\oo/\ 52 | * http://www.isthe.com/chongo/ 53 | * 54 | * Share and Enjoy! :-) 55 | */ 56 | #include 57 | #include "fnv.h" 58 | 59 | 60 | /* 61 | * 32 bit magic FNV-1a prime 62 | */ 63 | #define FNV_32_PRIME ((Fnv32_t)0x01000193) 64 | 65 | 66 | /* 67 | * fnv_32a_buf - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a buffer 68 | * 69 | * input: 70 | * buf - start of buffer to hash 71 | * len - length of buffer in octets 72 | * hval - previous hash value or 0 if first call 73 | * 74 | * returns: 75 | * 32 bit hash as a static hash type 76 | * 77 | * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the 78 | * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str(). 79 | */ 80 | Fnv32_t 81 | fnv_32a_buf(void *buf, size_t len, Fnv32_t hval) 82 | { 83 | unsigned char *bp = (unsigned char *)buf; /* start of buffer */ 84 | unsigned char *be = bp + len; /* beyond end of buffer */ 85 | 86 | /* 87 | * FNV-1a hash each octet in the buffer 88 | */ 89 | while (bp < be) { 90 | 91 | /* xor the bottom with the current octet */ 92 | hval ^= (Fnv32_t)*bp++; 93 | 94 | /* multiply by the 32 bit FNV magic prime mod 2^32 */ 95 | #if defined(NO_FNV_GCC_OPTIMIZATION) 96 | hval *= FNV_32_PRIME; 97 | #else 98 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 99 | #endif 100 | } 101 | 102 | /* return our new hash value */ 103 | return hval; 104 | } 105 | 106 | 107 | /* 108 | * fnv_32a_str - perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string 109 | * 110 | * input: 111 | * str - string to hash 112 | * hval - previous hash value or 0 if first call 113 | * 114 | * returns: 115 | * 32 bit hash as a static hash type 116 | * 117 | * NOTE: To use the recommended 32 bit FNV-1a hash, use FNV1_32A_INIT as the 118 | * hval arg on the first call to either fnv_32a_buf() or fnv_32a_str(). 119 | */ 120 | Fnv32_t 121 | fnv_32a_str(char *str, Fnv32_t hval) 122 | { 123 | unsigned char *s = (unsigned char *)str; /* unsigned string */ 124 | 125 | /* 126 | * FNV-1a hash each octet in the buffer 127 | */ 128 | while (*s) { 129 | 130 | /* xor the bottom with the current octet */ 131 | hval ^= (Fnv32_t)*s++; 132 | 133 | /* multiply by the 32 bit FNV magic prime mod 2^32 */ 134 | #if defined(NO_FNV_GCC_OPTIMIZATION) 135 | hval *= FNV_32_PRIME; 136 | #else 137 | hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); 138 | #endif 139 | } 140 | 141 | /* return our new hash value */ 142 | return hval; 143 | } 144 | -------------------------------------------------------------------------------- /thirdparty/fnv/license.txt: -------------------------------------------------------------------------------- 1 | This is the reference implementation of the FNV hash algorithm. 2 | It is placed in the public domain by the authors. 3 | 4 | See: http://www.isthe.com/chongo/tech/comp/fnv/index.html#public_domain 5 | 6 | -------------------------------------------------------------------------------- /thirdparty/glide3/3DFX.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $Revision: 9 $ 18 | ** $Date: 12/23/97 9:57a $ 19 | */ 20 | #ifndef __3DFX_H__ 21 | #define __3DFX_H__ 22 | 23 | /* 24 | ** basic data types 25 | */ 26 | typedef unsigned char FxU8; 27 | typedef signed char FxI8; 28 | typedef unsigned short FxU16; 29 | typedef signed short FxI16; 30 | typedef signed long FxI32; 31 | typedef unsigned long FxU32; 32 | typedef int FxBool; 33 | typedef float FxFloat; 34 | typedef double FxDouble; 35 | 36 | /* 37 | ** color types 38 | */ 39 | typedef unsigned long FxColor_t; 40 | typedef struct { float r, g, b, a; } FxColor4; 41 | 42 | /* 43 | ** fundamental types 44 | */ 45 | #define FXTRUE 1 46 | #define FXFALSE 0 47 | 48 | /* 49 | ** helper macros 50 | */ 51 | #define FXUNUSED( a ) ((void)(a)) 52 | #define FXBIT( i ) ( 1L << (i) ) 53 | 54 | /* 55 | ** export macros 56 | */ 57 | 58 | #if defined(__MSC__) 59 | # if defined (MSVC16) 60 | # define FX_ENTRY 61 | # define FX_CALL 62 | # else 63 | # define FX_ENTRY __declspec(dllexport) 64 | # define FX_CALL __stdcall 65 | # endif 66 | #elif defined(__WATCOMC__) 67 | # define FX_ENTRY extern 68 | # define FX_CALL __stdcall 69 | #elif defined (__IBMC__) || defined (__IBMCPP__) 70 | /* IBM Visual Age C/C++: */ 71 | # define FX_ENTRY extern 72 | # define FX_CALL __stdcall 73 | #elif defined(__DJGPP__) 74 | # define FX_ENTRY extern 75 | # define FX_CALL 76 | #elif defined(__unix__) 77 | # define FX_ENTRY extern 78 | # define FX_CALL 79 | #elif defined(__MWERKS__) 80 | # if macintosh 81 | # define FX_ENTRY extern 82 | # define FX_CALL 83 | # else /* !macintosh */ 84 | # error "Unknown MetroWerks target platform" 85 | # endif /* !macintosh */ 86 | #else 87 | # warning define FX_ENTRY & FX_CALL for your compiler 88 | # define FX_ENTRY extern 89 | # define FX_CALL 90 | #endif 91 | 92 | /* 93 | ** x86 compiler specific stuff 94 | */ 95 | #if defined(__BORLANDC_) 96 | # define REALMODE 97 | 98 | # define REGW( a, b ) ((a).x.b) 99 | # define REGB( a, b ) ((a).h.b) 100 | # define INT86( a, b, c ) int86(a,b,c) 101 | # define INT86X( a, b, c, d ) int86x(a,b,c,d) 102 | 103 | # define RM_SEG( a ) FP_SEG( a ) 104 | # define RM_OFF( a ) FP_OFF( a ) 105 | #elif defined(__WATCOMC__) 106 | # undef FP_SEG 107 | # undef FP_OFF 108 | 109 | # define REGW( a, b ) ((a).w.b) 110 | # define REGB( a, b ) ((a).h.b) 111 | # define INT86( a, b, c ) int386(a,b,c) 112 | # define INT86X( a, b, c, d ) int386x(a,b,c,d) 113 | 114 | # define RM_SEG( a ) ( ( ( ( FxU32 ) (a) ) & 0x000F0000 ) >> 4 ) 115 | # define RM_OFF( a ) ( ( FxU16 ) (a) ) 116 | #endif 117 | 118 | #endif /* !__3DFX_H__ */ 119 | -------------------------------------------------------------------------------- /thirdparty/glide3/FXDLL.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 1996, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $Revision: 9 $ 18 | ** $Date: 7/24/98 1:37p $ 19 | */ 20 | /* preprocessor defines for libraries to support DLL creation */ 21 | 22 | /* in header file, use FX_ENTRY return-type FX_CALL function-name ( ... ) */ 23 | /* in source file, use FX_EXPORT return-type FX_CSTYLE function-name (... ) */ 24 | 25 | /* in source file, set FX_DLL_DEFINITION, include this file, then include 26 | header file for library. */ 27 | 28 | /* we need to use two macros per declaration/definition because MSVC 29 | requires __stdcall and __declspec( dllexport ) be in different parts 30 | of the prototype! */ 31 | 32 | /* I use two sets in case we need to control declarations and definitions 33 | differently. If it turns out we don't, it should be easy to do a search 34 | and replace to eliminate one set */ 35 | 36 | /* NOTE: this header file may be included more than once, and FX_DLL_DEFINITION 37 | may have changed, so we do not protect this with an #fndef __FXDLL_H__ 38 | statement like we normally would. */ 39 | 40 | 41 | #ifdef FX_ENTRY 42 | #undef FX_ENTRY 43 | #endif 44 | 45 | #ifdef FX_CALL 46 | #undef FX_CALL 47 | #endif 48 | 49 | #ifdef FX_EXPORT 50 | #undef FX_EXPORT 51 | #endif 52 | 53 | #ifdef FX_CSTYLE 54 | #undef FX_CSTYLE 55 | #endif 56 | 57 | #if defined(FX_DLL_DEFINITION) 58 | #if defined(FX_DLL_ENABLE) 59 | #if defined(__MSC__) 60 | #ifndef KERNEL 61 | #define FX_ENTRY __declspec( dllexport ) 62 | #define FX_EXPORT __declspec( dllexport ) 63 | #else 64 | #define FX_ENTRY 65 | #define FX_EXPORT 66 | #endif /* #ifndef KERNEL */ 67 | #define FX_CALL __stdcall 68 | #define FX_CSTYLE __stdcall 69 | 70 | #elif defined(__WATCOMC__) 71 | #define FX_ENTRY 72 | #define FX_CALL __stdcall __export 73 | 74 | #define FX_EXPORT 75 | #define FX_CSTYLE __stdcall __export 76 | 77 | #else /* compiler */ 78 | #error define FX_ENTRY,FX_CALL & FX_EXPORT,FX_CSTYLE for your compiler 79 | #endif /* compiler */ 80 | 81 | #else /* FX_DLL_ENABLE */ 82 | #define FX_ENTRY 83 | #define FX_CALL __stdcall 84 | 85 | #define FX_EXPORT 86 | #define FX_CSTYLE __stdcall 87 | #endif /* FX_DLL_ENABLE */ 88 | 89 | #else /* FX_DLL_DEFINITION */ 90 | #define FX_ENTRY extern 91 | #define FX_CALL __stdcall 92 | #endif /* FX_DLL_DEFINITION */ 93 | 94 | /* 95 | * We don't want any of this DLL junk for DJGPP or UNIX 96 | * so undo what is done above. 97 | */ 98 | #if defined(__DJGPP__) || defined(__unix__) 99 | #ifdef FX_CALL 100 | #undef FX_CALL 101 | #endif 102 | 103 | #ifdef FX_CSTYLE 104 | #undef FX_CSTYLE 105 | #endif 106 | 107 | #ifdef FX_EXPORT 108 | #undef FX_EXPORT 109 | #endif 110 | 111 | #ifdef FX_ENTRY 112 | #undef FX_ENTRY 113 | #endif 114 | 115 | #define FX_CALL 116 | #define FX_CSTYLE 117 | #define FX_EXPORT 118 | #define FX_ENTRY 119 | #endif 120 | 121 | #if defined (MSVC16) 122 | #undef FX_CALL 123 | #define FX_CALL 124 | #endif 125 | 126 | -------------------------------------------------------------------------------- /thirdparty/glide3/FXGLOB.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $ Revision: $ 18 | ** $ Date: $ 19 | ** 20 | */ 21 | 22 | 23 | #ifndef _FXGLOB_H_ 24 | #define _FXGLOB_H_ 25 | 26 | 27 | void fxGlobify( int *argc, char ***argv ); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /thirdparty/glide3/FXOS.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $ Revision: $ 18 | ** $ Date: $ 19 | ** 20 | */ 21 | 22 | 23 | #ifndef _FXOS_H_ 24 | #define _FXOS_H_ 25 | 26 | #include 27 | 28 | # ifdef __cplusplus 29 | extern "C" { 30 | # endif 31 | 32 | # ifdef WIN32 33 | void sleep(int secs); 34 | #define gethostname fxGethostname 35 | 36 | int gethostname(char *name, int namelen); 37 | 38 | # endif 39 | 40 | float fxTime(void); 41 | float timer(int flag); 42 | 43 | FILE *fxFopenPath(const char *filename, const char *mode, 44 | const char *path, const char **pprefix); 45 | 46 | # ifdef __cplusplus 47 | } 48 | # endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /thirdparty/glide3/SST1VID.H: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $Header: /devel/cvg/incsrc/SST1VID.H 6 7/24/98 1:41p Hohn $ 18 | ** $Log: /devel/cvg/incsrc/SST1VID.H $ 19 | ** 20 | ** 6 7/24/98 1:41p Hohn 21 | ** 22 | ** 5 3/10/98 2:33p Psmith 23 | ** separating cvg tree from h3/h4 trees 24 | * 25 | * 4 9/09/97 7:35p Sellers 26 | * Added 400x300 resolution 27 | * 28 | * 3 8/24/97 9:31a Sellers 29 | * moved new video timing to sst1vid.h 30 | * redefined 1600x1280 to be 1600x1200 31 | * 32 | * 2 6/05/97 11:14p Pgj 33 | * 34 | * 5 7/24/96 3:43p Sellers 35 | * added 512x384 @ 60 Hz for arcade monitors 36 | * added 512x256 @ 60 Hz for arcade monitors 37 | * 38 | * 4 7/18/96 10:58a Sellers 39 | * fixed FT and TF clock delay values for lower frequencies with 40 | * .5/.5 combos 41 | * 42 | * 3 6/18/96 6:54p Sellers 43 | * added sst1InitShutdownSli() to fix Glide Splash screen problems with 44 | * SLI 45 | * 46 | * 2 6/13/96 7:45p Sellers 47 | * added "voodoo.ini" support 48 | * added DirectX support 49 | * misc cleanup 50 | * 51 | * 2 6/11/96 1:43p Sellers 52 | * added support for 60, 75, 85, and 120 Hz refresh rates for "most" 53 | * resolutions 54 | * 55 | * 1 5/08/96 5:43p Paik 56 | * Video definitions 57 | */ 58 | #ifndef __SST1VID_H__ 59 | #define __SST1VID_H__ 60 | 61 | #ifdef __cplusplus 62 | extern "C" { 63 | #endif 64 | 65 | /* Video defines */ 66 | 67 | typedef FxI32 GrScreenRefresh_t; 68 | #define GR_REFRESH_60Hz 0x0 69 | #define GR_REFRESH_70Hz 0x1 70 | #define GR_REFRESH_72Hz 0x2 71 | #define GR_REFRESH_75Hz 0x3 72 | #define GR_REFRESH_80Hz 0x4 73 | #define GR_REFRESH_90Hz 0x5 74 | #define GR_REFRESH_100Hz 0x6 75 | #define GR_REFRESH_85Hz 0x7 76 | #define GR_REFRESH_120Hz 0x8 77 | #define GR_REFRESH_NONE 0xff 78 | 79 | typedef FxI32 GrScreenResolution_t; 80 | #define GR_RESOLUTION_320x200 0x0 81 | #define GR_RESOLUTION_320x240 0x1 82 | #define GR_RESOLUTION_400x256 0x2 83 | #define GR_RESOLUTION_512x384 0x3 84 | #define GR_RESOLUTION_640x200 0x4 85 | #define GR_RESOLUTION_640x350 0x5 86 | #define GR_RESOLUTION_640x400 0x6 87 | #define GR_RESOLUTION_640x480 0x7 88 | #define GR_RESOLUTION_800x600 0x8 89 | #define GR_RESOLUTION_960x720 0x9 90 | #define GR_RESOLUTION_856x480 0xa 91 | #define GR_RESOLUTION_512x256 0xb 92 | #define GR_RESOLUTION_1024x768 0xC 93 | #define GR_RESOLUTION_1280x1024 0xD 94 | #define GR_RESOLUTION_1600x1200 0xE 95 | #define GR_RESOLUTION_400x300 0xF 96 | #define GR_RESOLUTION_NONE 0xff 97 | 98 | #ifdef GR_RESOLUTION_MAX 99 | #undef GR_RESOLUTION_MAX 100 | #endif 101 | #ifdef GR_RESOLUTION_MIN 102 | #undef GR_RESOLUTION_MIN 103 | #endif 104 | #define GR_RESOLUTION_MIN GR_RESOLUTION_320x200 105 | #define GR_RESOLUTION_MAX GR_RESOLUTION_1600x1200 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | 111 | #endif /* __SST1VID_H__ */ 112 | -------------------------------------------------------------------------------- /thirdparty/glide3/glidesys.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | n** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $Header: /devel/cvg/glide3/src/glidesys.h 3 7/24/98 1:41p Hohn $ 18 | ** $Log: /devel/cvg/glide3/src/glidesys.h $ 19 | ** 20 | ** 3 7/24/98 1:41p Hohn 21 | ** 22 | ** 2 6/15/98 10:50a Peter 23 | ** made csim compile time option 24 | * 25 | * 1 1/16/98 4:29p Atai 26 | * create glide 3 src 27 | * 28 | * 10 12/09/97 12:20p Peter 29 | * mac glide port 30 | * 31 | * 9 11/04/97 4:00p Dow 32 | * Banshee Mods 33 | * 34 | * 8 8/18/97 3:52p Peter 35 | * pre-hw arrival fixes/cleanup 36 | * 37 | * 7 6/02/97 4:09p Peter 38 | * Compile w/ gcc for Dural 39 | * 40 | * 6 5/27/97 1:16p Peter 41 | * Basic cvg, w/o cmd fifo stuff. 42 | * 43 | * 5 5/21/97 6:05a Peter 44 | */ 45 | #ifndef __GLIDESYS_H__ 46 | #define __GLIDESYS_H__ 47 | 48 | /* 49 | n** ----------------------------------------------------------------------- 50 | ** COMPILER/ENVIRONMENT CONFIGURATION 51 | ** ----------------------------------------------------------------------- 52 | */ 53 | 54 | /* Endianness is stored in bits [30:31] */ 55 | #define GLIDE_ENDIAN_SHIFT 30 56 | #define GLIDE_ENDIAN_LITTLE (0x1 << GLIDE_ENDIAN_SHIFT) 57 | #define GLIDE_ENDIAN_BIG (0x2 << GLIDE_ENDIAN_SHIFT) 58 | 59 | /* OS is stored in bits [0:6] */ 60 | #define GLIDE_OS_SHIFT 0 61 | #define GLIDE_OS_UNIX 0x1 62 | #define GLIDE_OS_DOS32 0x2 63 | #define GLIDE_OS_WIN32 0x4 64 | #define GLIDE_OS_MACOS 0x8 65 | #define GLIDE_OS_OS2 0x10 66 | #define GLIDE_OS_OTHER 0x40 /* For Proprietary Arcade HW */ 67 | 68 | /* Sim vs. Hardware is stored in bits [7:8] */ 69 | #define GLIDE_SST_SHIFT 7 70 | #define GLIDE_SST_SIM (0x1 << GLIDE_SST_SHIFT) 71 | #define GLIDE_SST_HW (0x2 << GLIDE_SST_SHIFT) 72 | 73 | /* Hardware Type is stored in bits [9:13] */ 74 | #define GLIDE_HW_SHIFT 9 75 | #define GLIDE_HW_SST1 (0x1 << GLIDE_HW_SHIFT) 76 | #define GLIDE_HW_SST96 (0x2 << GLIDE_HW_SHIFT) 77 | #define GLIDE_HW_H3 (0x4 << GLIDE_HW_SHIFT) 78 | #define GLIDE_HW_SST2 (0x8 << GLIDE_HW_SHIFT) 79 | #define GLIDE_HW_CVG (0x10 << GLIDE_HW_SHIFT) 80 | 81 | /* 82 | ** Make sure we handle all instances of WIN32 83 | */ 84 | #ifndef __WIN32__ 85 | # if defined (_WIN32) || defined (WIN32) || defined(__NT__) 86 | # define __WIN32__ 87 | # endif 88 | #endif 89 | 90 | /* We need two checks on the OS: one for endian, the other for OS */ 91 | /* Check for endianness */ 92 | #if defined(__IRIX__) || defined(__sparc__) || defined(MACOS) 93 | # define GLIDE_ENDIAN GLIDE_ENDIAN_BIG 94 | #else 95 | # define GLIDE_ENDIAN GLIDE_ENDIAN_LITTLE 96 | #endif 97 | 98 | /* Check for OS */ 99 | #if defined(__IRIX__) || defined(__sparc__) || defined(__linux__) 100 | # define GLIDE_OS GLIDE_OS_UNIX 101 | #elif defined(__DOS__) 102 | # define GLIDE_OS GLIDE_OS_DOS32 103 | #elif defined(__WIN32__) 104 | # define GLIDE_OS GLIDE_OS_WIN32 105 | #elif defined(macintosh) 106 | # define GLIDE_OS GLIDE_OS_MACOS 107 | #else 108 | #error "Unknown OS" 109 | #endif 110 | 111 | /* Check for Simulator vs. Hardware */ 112 | #if HAL_CSIM || HWC_CSIM 113 | # define GLIDE_SST GLIDE_SST_SIM 114 | #else 115 | # define GLIDE_SST GLIDE_SST_HW 116 | #endif 117 | 118 | /* Check for type of hardware */ 119 | #ifdef SST96 120 | # define GLIDE_HW GLIDE_HW_SST96 121 | #elif defined(H3) 122 | # define GLIDE_HW GLIDE_HW_H3 123 | #elif defined(SST2) 124 | # define GLIDE_HW GLIDE_HW_SST2 125 | #elif defined(CVG) 126 | # define GLIDE_HW GLIDE_HW_CVG 127 | #else /* Default to SST1 */ 128 | # define GLIDE_HW GLIDE_HW_SST1 129 | #endif 130 | 131 | 132 | #define GLIDE_PLATFORM (GLIDE_ENDIAN | GLIDE_OS | GLIDE_SST | GLIDE_HW) 133 | 134 | /* 135 | ** Control the number of TMUs 136 | */ 137 | #ifndef GLIDE_NUM_TMU 138 | # define GLIDE_NUM_TMU 2 139 | #endif 140 | 141 | 142 | #if ((GLIDE_NUM_TMU < 0) && (GLIDE_NUM_TMU > 3)) 143 | # error "GLIDE_NUM_TMU set to an invalid value" 144 | #endif 145 | 146 | #endif /* __GLIDESYS_H__ */ 147 | -------------------------------------------------------------------------------- /thirdparty/glide3/glideutl.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 1995, 3Dfx Interactive, Inc. 3 | ** All Rights Reserved. 4 | ** 5 | ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.; 6 | ** the contents of this file may not be disclosed to third parties, copied or 7 | ** duplicated in any form, in whole or in part, without the prior written 8 | ** permission of 3Dfx Interactive, Inc. 9 | ** 10 | ** RESTRICTED RIGHTS LEGEND: 11 | ** Use, duplication or disclosure by the Government is subject to restrictions 12 | ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data 13 | ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or 14 | ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished - 15 | ** rights reserved under the Copyright Laws of the United States. 16 | ** 17 | ** $Header: /devel/cvg/glide3/src/glideutl.h 4 7/24/98 1:41p Hohn $ 18 | ** $Log: /devel/cvg/glide3/src/glideutl.h $ 19 | ** 20 | ** 4 7/24/98 1:41p Hohn 21 | ** 22 | ** 3 1/30/98 4:27p Atai 23 | ** gufog* prototype 24 | ** 25 | ** 1 1/29/98 4:00p Atai 26 | * 27 | * 1 1/16/98 4:29p Atai 28 | * create glide 3 src 29 | * 30 | * 11 1/07/98 11:18a Atai 31 | * remove GrMipMapInfo and GrGC.mm_table in glide3 32 | * 33 | * 10 1/06/98 6:47p Atai 34 | * undo grSplash and remove gu routines 35 | * 36 | * 9 1/05/98 6:04p Atai 37 | * move 3df gu related data structure from glide.h to glideutl.h 38 | * 39 | * 8 12/18/97 2:13p Peter 40 | * fogTable cataclysm 41 | * 42 | * 7 12/15/97 5:52p Atai 43 | * disable obsolete glide2 api for glide3 44 | * 45 | * 6 8/14/97 5:32p Pgj 46 | * remove dead code per GMT 47 | * 48 | * 5 6/12/97 5:19p Pgj 49 | * Fix bug 578 50 | * 51 | * 4 3/05/97 9:36p Jdt 52 | * Removed guFbWriteRegion added guEncodeRLE16 53 | * 54 | * 3 1/16/97 3:45p Dow 55 | * Embedded fn protos in ifndef FX_GLIDE_NO_FUNC_PROTO 56 | */ 57 | 58 | /* Glide Utility routines */ 59 | 60 | #ifndef __GLIDEUTL_H__ 61 | #define __GLIDEUTL_H__ 62 | 63 | #ifdef __cplusplus 64 | extern "C" { 65 | #endif 66 | 67 | /* 68 | ** 3DF texture file structs 69 | */ 70 | 71 | typedef struct 72 | { 73 | FxU32 width, height; 74 | int small_lod, large_lod; 75 | GrAspectRatio_t aspect_ratio; 76 | GrTextureFormat_t format; 77 | } Gu3dfHeader; 78 | 79 | typedef struct 80 | { 81 | FxU8 yRGB[16]; 82 | FxI16 iRGB[4][3]; 83 | FxI16 qRGB[4][3]; 84 | FxU32 packed_data[12]; 85 | } GuNccTable; 86 | 87 | typedef struct { 88 | FxU32 data[256]; 89 | } GuTexPalette; 90 | 91 | typedef union { 92 | GuNccTable nccTable; 93 | GuTexPalette palette; 94 | } GuTexTable; 95 | 96 | typedef struct 97 | { 98 | Gu3dfHeader header; 99 | GuTexTable table; 100 | void *data; 101 | FxU32 mem_required; /* memory required for mip map in bytes. */ 102 | } Gu3dfInfo; 103 | 104 | #ifndef FX_GLIDE_NO_FUNC_PROTO 105 | /* 106 | ** Gamma functions 107 | */ 108 | 109 | FX_ENTRY void FX_CALL 110 | guGammaCorrectionRGB( FxFloat red, FxFloat green, FxFloat blue ); 111 | 112 | /* 113 | ** fog stuff 114 | */ 115 | FX_ENTRY float FX_CALL 116 | guFogTableIndexToW( int i ); 117 | 118 | FX_ENTRY void FX_CALL 119 | guFogGenerateExp( GrFog_t *fogtable, float density ); 120 | 121 | FX_ENTRY void FX_CALL 122 | guFogGenerateExp2( GrFog_t *fogtable, float density ); 123 | 124 | FX_ENTRY void FX_CALL 125 | guFogGenerateLinear(GrFog_t *fogtable, 126 | float nearZ, float farZ ); 127 | 128 | /* 129 | ** hi-level texture manipulation tools. 130 | */ 131 | FX_ENTRY FxBool FX_CALL 132 | gu3dfGetInfo( const char *filename, Gu3dfInfo *info ); 133 | 134 | FX_ENTRY FxBool FX_CALL 135 | gu3dfLoad( const char *filename, Gu3dfInfo *data ); 136 | 137 | #endif /* FX_GLIDE_NO_FUNC_PROTO */ 138 | 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif /* __GLIDEUTL_H__ */ 144 | -------------------------------------------------------------------------------- /thirdparty/pocketlzma/pocketlzma-LICENSE.txt: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2020, Robin Berg Pettersen 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes - Changelog.txt: -------------------------------------------------------------------------------- 1 | [SGD2FreeRes 3.0.2.0 (May 1, 2021)] 2 | - Restore support for 1.13D. 3 | - Add support for 1.14C and 1.14D. 4 | - Add support for D2DX Glide wrapper. Special thanks to bolrog for 5 | providing the extended API in D2DX. 6 | - Add 856x480 resolution to all existing gateways. 7 | - Add 1068x600 resolution to D2LOD.NET. 8 | - Fix potential incorrect display of DirectDraw video mode. 9 | - Fix config wiping when JSON is not valid. 10 | - Display a warning and exit if the config is not valid JSON. 11 | 12 | [SGD2FreeRes 3.0.1.1B (March 27, 2021)] 13 | - Add D2LOD.NET support. The custom resolution is 1024x768. 14 | 15 | [SGD2FreeRes 3.0.1.1 (March 23, 2021)] 16 | - Add ProjectDiablo 2 support. 17 | - Fix version detection bug that prevented D2SE from launching even 18 | with valid values. 19 | - Fix incorrect inventory positions caused by some resolution 20 | configurations. 21 | - Fix transfer of inventory arrangement positions between SP and MP. 22 | 23 | [SGD2FreeRes 3.0.1.0 (March 13, 2021)] 24 | - Restore support for 1.13C. 25 | - Support D2SE. Must be loaded using the PlugY.ini config. 26 | - Fix video mode detection always incorrectly detecting DirectDraw 27 | when game video mode is not controlled by command line options. 28 | - Fix default assets mismatch for the right screen's border. 29 | - Fix potential bug that may result in the New Skill button not 30 | appearing correctly. 31 | 32 | 1.13C Only: 33 | - Fix the aspect ratio window scaling when the maximize button is 34 | pressed. Previously, the maximize button only scaled for 4:3 aspect 35 | ratio even when the resolution's aspect ratio was different. 36 | - Fix the restore down functionality when the maximize button is 37 | pressed. Previously, the button would prevent re-maximizing the 38 | game window when pressed. 39 | 40 | Known issues: 41 | - In 1.09D, Glide mode will sometimes crash from failed ingame 42 | assertion "nIndex != INVALID_HARDWARE". It is currently unknown how 43 | to consistently replicate the error. 44 | - Glide mode displays incorrectly when the maximize button is pressed. 45 | 46 | [SGD2FreeRes 3.0.0.1 (Feb 26, 2021)] 47 | - Support usage of CnC-DDraw as the DDraw wrapper. 48 | - Reduce file size through optimization and the removal of code bloat. 49 | - Fix incompatibility with PlugY. 50 | - Fix improper resolution selection when largest resolution is set, 51 | and 640x480 is excluded in resolution definitions. 52 | 53 | Known issues (since last patch): 54 | - In 1.09D, Glide mode will sometimes crash from failed ingame 55 | assertion "nIndex != INVALID_HARDWARE". It is currently unknown how 56 | to consistently replicate the error. 57 | 58 | [SGD2FreeRes 3.0.0.0 (Dec 12, 2020)] 59 | - Rename the project to SGD2FreeRes, as the project can provide more 60 | than just HD. Also sorts out confusion from folks who conflate HD 61 | with higher quality graphics. 62 | - Rewrite from the ground up, replacing D2Template with SGD2MAPI as 63 | its core. 64 | - Supports 1.09D, support for the other version need to be 65 | ported back in at a later time. 66 | - Use JSON format for config file. 67 | - Uncap single player resolution. Resolutions can be added in the 68 | config file. 69 | - Cap multiplayer resolution is depending on the gateway. 70 | - Support usage of nGlide as the Glide wrapper. 71 | - Fix video option selection crash that would occur when Lighting 72 | Quality is selected under certain circumstances. 73 | - Fix Windows 10 error on game exit, when Sven's Glide Wrapper is 74 | present, but the video mode was not Glide. 75 | 76 | [D2HD 2.0.1.1 (Approx. Mar 2018 - Nov 2018)] 77 | - Add support for 1.12. 78 | - Fix window resize issue upon game exit. 79 | - Fix crash when using a non-standard resolution in DirectDraw or 80 | Direct3D video mode. 81 | 82 | [D2HD 2.0.1.0 (Approx. Mar 2018 - Nov 2018)] 83 | - Set resolution to 1068x600, as Slash wants to maintain consistency 84 | with Resurgence. 85 | 86 | [D2HD 2.0.1.0 Internal Release Candidate (Approx. Mar 2018 - Nov 2018)] 87 | - Set resolution to 1344x700, in case Slash wants to go with the 88 | higher resolution. 89 | 90 | [D2HD 2.0.0.1 (Approx. Dec 2017 - Mar 2018)] 91 | - Fix resolution reload on first game created. Would lag the game, 92 | especially in Chaos Sanctuary. 93 | 94 | [D2HD 2.0 (Approx. June - July 2017] 95 | - Restore 640x480 resolution. New resolutions are added on top of 96 | existing resolutions. 97 | - (Possibly) added support for 1.13D. 98 | 99 | [D2HD 1.0 (Approx. May 2017)] 100 | - Replace 640x480 with 1068x600. 101 | - Only supports 1.13C. 102 | -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes - README.md: -------------------------------------------------------------------------------- 1 | # SlashGaming Diablo II Free Resolution (SGD2FreeRes) 2 | This is a project aimed at modding Diablo II to support any resolution. 3 | 4 | ## Features 5 | - Enables selecting user-specified resolutions from the Video Options menu. 6 | - Automatically adjusts the positions of inventory and UI elements, using 800x600 as a base for positions. 7 | - Allows limited customization of the UI. 8 | 9 | ## Compatibility 10 | - Supports 1.09D, 1.13C, 1.13D, 1.14C, and 1.14D. 11 | - Supports multiple video modes. 12 | - Supports standard GDI mode. Resolutions are unrestricted. 13 | - Supports standard DirectDraw and Direct3D modes, restricted to "standard" resolutions. 14 | - Supports CnC-DDraw wrapper. Resolutions are unrestricted. 15 | - Supports [Sven's Glide wrapper](http://www.svenswrapper.de/english/), [nGlide](https://www.zeus-software.com/), and [D2DX](https://github.com/bolrog/d2dx) Glide wrapper. Resolutions are unrestricted. 16 | - Compatibility with select modsystems. 17 | - [PlugY](http://plugy.free.fr/en/index.html) 18 | - [D2SE](https://snej.org/forum/index2.php?topic=18954.msg459574#msg459574) 19 | 20 | ## Usage 21 | The DLL does nothing on its own and must be loaded into the game via external tools. Once loaded, the game will need to be run in order to generate the config file for the first time. Singleplayer resolutions, along with other configuration options can be configured to the preferences of the user. 22 | 23 | ## Multiplayer Use 24 | Multiplayer use is restricted to certain gateways. This cannot be changed easily and prevents unintentional abuse where it is not allowed (i.e. Battle.net). If used in unpermitted environments, the resolution is hardcoded to run with only 640x480 or 800x600. It is also still possible to be detected by anti-cheat systems and be banned for unauthorized modification of the game client, even if the functionality is ineffective. Where it is permitted, the resolutions are preset for the server. 25 | 26 | Any server owner that wishes to authorize the usage of SGD2FreeRes on their server should contact Mir Drualga on the SlashDiablo Discord. 27 | 28 | Servers that permit SGD2FreeRes: 29 | - [Diablo 09](https://www.diablo09.com/): 640x480, 800x600, 856x480, 1068x600 30 | - [SlashDiablo](https://slashdiablo.net/): 640x480, 800x600, 856x480, 1068x600 31 | - [Resurgence](https://resurgence.slashgaming.net/): 640x480, 800x600, 856x480, 1068x600 32 | - [Project Diablo 2](https://www.projectdiablo2.com/): 640x480, 800x600, 856x480, 1068x600 33 | - [D2LOD.NET](http://d2lod.net/): 640x480, 800x600, 856x480, 1024x768, 1068x600 34 | 35 | ## Contribution 36 | SGD2FreeRes is coded in C++20. It currently is intended to compile with Visual Studio 2019. 37 | 38 | The linker needs to be configured to link the DLL to version.lib, MDCc.lib, MDCcpp98.lib and SGD2MAPI.lib. 39 | 40 | When you submit a pull request, you certify that the code in the pull request is AGPLv3+ compatible. You also certify that you have authorization to submit the pull request with the code changes. You certify that the merging of the pull request with those changes is authorized under the license terms of the AGPLv3+. Finally, you certify that the contribution is licensed under the AGPLv3+. 41 | 42 | ## Thanks 43 | - [/r/SlashDiablo](https://www.reddit.com/r/slashdiablo/): The community that got me started. The whole reason the project took off. 44 | - [PhrozenKeep](https://d2mods.info/): Community with plenty of information on Diablo II, modding, and resources. 45 | - [balrog](https://github.com/bolrog): For providing an extended API to enable interfacing with the D2DX Glide wrapper. 46 | 47 | ## Legal 48 | The project is licensed under the terms of the Affero General Public License, version 3 or higher, with exceptions. Components may be licensed under other terms, so check LICENSE for more details. If you wish to apply for a proprietary license exception, please contact Mir Drualga on the SlashDiablo Discord channel. 49 | 50 | Diablo II and Diablo II: Lord of Destruction are registered trademarks of Blizzard Entertainment. This project is not affiliated with Blizzard Entertainment in any way. 51 | -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/sgd2freeres/SGD2FreeRes.dll -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes.dll.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/sgd2freeres/SGD2FreeRes.dll.lzma -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes.mpq: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/sgd2freeres/SGD2FreeRes.mpq -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes.mpq.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/sgd2freeres/SGD2FreeRes.mpq.lzma -------------------------------------------------------------------------------- /thirdparty/sgd2freeres/SGD2FreeRes.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/sgd2freeres/SGD2FreeRes.pdb -------------------------------------------------------------------------------- /thirdparty/toml/toml.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bolrog/d2dx/d95d19a44265114856885bf3c60060b32b880d7d/thirdparty/toml/toml.c -------------------------------------------------------------------------------- /toml-LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 CK Tan 4 | https://github.com/cktan/tomlc99 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | --------------------------------------------------------------------------------