├── .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 |
--------------------------------------------------------------------------------