├── .gitattributes ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── FW-KENSC-ShellExt.iss ├── FW-KENSC-ShellExt.sln ├── FW-KENSC-ShellExt ├── ClassFactory.cpp ├── ClassFactory.h ├── ContextMenu.cpp ├── ContextMenu.h ├── FW-KENSC-ShellExt.def ├── FW-KENSC-ShellExt.vcxproj ├── FW-KENSC-ShellExt.vcxproj.filters ├── ReadMe.txt ├── Twizzler │ ├── Twizzler.cpp │ └── Twizzler.h ├── dllmain.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Typical CMake build directory. 2 | /build 3 | 4 | ## Ignore Visual Studio temporary files, build results, and 5 | ## files generated by popular Visual Studio add-ons. 6 | 7 | # User-specific files 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | project.fragment.lock.json 49 | artifacts/ 50 | Properties/launchSettings.json 51 | 52 | *_i.c 53 | *_p.c 54 | *_i.h 55 | *.ilk 56 | *.meta 57 | *.obj 58 | *.pch 59 | *.pdb 60 | *.pgc 61 | *.pgd 62 | *.rsp 63 | *.sbr 64 | *.tlb 65 | *.tli 66 | *.tlh 67 | *.tmp 68 | *.tmp_proj 69 | *.log 70 | *.vspscc 71 | *.vssscc 72 | .builds 73 | *.pidb 74 | *.svclog 75 | *.scc 76 | 77 | # Chutzpah Test files 78 | _Chutzpah* 79 | 80 | # Visual C++ cache files 81 | ipch/ 82 | *.aps 83 | *.ncb 84 | *.opendb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | *.VC.db 89 | *.VC.VC.opendb 90 | 91 | # Visual Studio profiler 92 | *.psess 93 | *.vsp 94 | *.vspx 95 | *.sap 96 | 97 | # TFS 2012 Local Workspace 98 | $tf/ 99 | 100 | # Guidance Automation Toolkit 101 | *.gpState 102 | 103 | # ReSharper is a .NET coding add-in 104 | _ReSharper*/ 105 | *.[Rr]e[Ss]harper 106 | *.DotSettings.user 107 | 108 | # JustCode is a .NET coding add-in 109 | .JustCode 110 | 111 | # TeamCity is a build add-in 112 | _TeamCity* 113 | 114 | # DotCover is a Code Coverage Tool 115 | *.dotCover 116 | 117 | # Visual Studio code coverage results 118 | *.coverage 119 | *.coveragexml 120 | 121 | # NCrunch 122 | _NCrunch_* 123 | .*crunch*.local.xml 124 | nCrunchTemp_* 125 | 126 | # MightyMoose 127 | *.mm.* 128 | AutoTest.Net/ 129 | 130 | # Web workbench (sass) 131 | .sass-cache/ 132 | 133 | # Installshield output folder 134 | [Ee]xpress/ 135 | 136 | # DocProject is a documentation generator add-in 137 | DocProject/buildhelp/ 138 | DocProject/Help/*.HxT 139 | DocProject/Help/*.HxC 140 | DocProject/Help/*.hhc 141 | DocProject/Help/*.hhk 142 | DocProject/Help/*.hhp 143 | DocProject/Help/Html2 144 | DocProject/Help/html 145 | 146 | # Click-Once directory 147 | publish/ 148 | 149 | # Publish Web Output 150 | *.[Pp]ublish.xml 151 | *.azurePubxml 152 | # TODO: Comment the next line if you want to checkin your web deploy settings 153 | # but database connection strings (with potential passwords) will be unencrypted 154 | *.pubxml 155 | *.publishproj 156 | 157 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 158 | # checkin your Azure Web App publish settings, but sensitive information contained 159 | # in these scripts will be unencrypted 160 | PublishScripts/ 161 | 162 | # NuGet Packages 163 | *.nupkg 164 | # The packages folder can be ignored because of Package Restore 165 | **/packages/* 166 | # except build/, which is used as an MSBuild target. 167 | !**/packages/build/ 168 | # Uncomment if necessary however generally it will be regenerated when needed 169 | #!**/packages/repositories.config 170 | # NuGet v3's project.json files produces more ignoreable files 171 | *.nuget.props 172 | *.nuget.targets 173 | 174 | # Microsoft Azure Build Output 175 | csx/ 176 | *.build.csdef 177 | 178 | # Microsoft Azure Emulator 179 | ecf/ 180 | rcf/ 181 | 182 | # Windows Store app package directories and files 183 | AppPackages/ 184 | BundleArtifacts/ 185 | Package.StoreAssociation.xml 186 | _pkginfo.txt 187 | 188 | # Visual Studio cache files 189 | # files ending in .cache can be ignored 190 | *.[Cc]ache 191 | # but keep track of directories ending in .cache 192 | !*.[Cc]ache/ 193 | 194 | # Others 195 | ClientBin/ 196 | ~$* 197 | *~ 198 | *.dbmdl 199 | *.dbproj.schemaview 200 | *.jfm 201 | *.pfx 202 | *.publishsettings 203 | node_modules/ 204 | orleans.codegen.cs 205 | 206 | # Since there are multiple workflows, uncomment next line to ignore bower_components 207 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 208 | #bower_components/ 209 | 210 | # RIA/Silverlight projects 211 | Generated_Code/ 212 | 213 | # Backup & report files from converting an old project file 214 | # to a newer Visual Studio version. Backup files are not needed, 215 | # because we have git ;-) 216 | _UpgradeReport_Files/ 217 | Backup*/ 218 | UpgradeLog*.XML 219 | UpgradeLog*.htm 220 | 221 | # SQL Server files 222 | *.mdf 223 | *.ldf 224 | 225 | # Business Intelligence projects 226 | *.rdl.data 227 | *.bim.layout 228 | *.bim_*.settings 229 | 230 | # Microsoft Fakes 231 | FakesAssemblies/ 232 | 233 | # GhostDoc plugin setting file 234 | *.GhostDoc.xml 235 | 236 | # Node.js Tools for Visual Studio 237 | .ntvs_analysis.dat 238 | 239 | # Visual Studio 6 build log 240 | *.plg 241 | 242 | # Visual Studio 6 workspace options file 243 | *.opt 244 | 245 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 246 | *.vbw 247 | 248 | # Visual Studio LightSwitch build output 249 | **/*.HTMLClient/GeneratedArtifacts 250 | **/*.DesktopClient/GeneratedArtifacts 251 | **/*.DesktopClient/ModelManifest.xml 252 | **/*.Server/GeneratedArtifacts 253 | **/*.Server/ModelManifest.xml 254 | _Pvt_Extensions 255 | 256 | # Paket dependency manager 257 | .paket/paket.exe 258 | paket-files/ 259 | 260 | # FAKE - F# Make 261 | .fake/ 262 | 263 | # JetBrains Rider 264 | .idea/ 265 | *.sln.iml 266 | 267 | # CodeRush 268 | .cr/ 269 | 270 | # Python Tools for Visual Studio (PTVS) 271 | __pycache__/ 272 | *.pyc 273 | 274 | # Cake - Uncomment if you are using it 275 | # tools/ 276 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "FW-KENSC-ShellExt/mdcomp"] 2 | path = FW-KENSC-ShellExt/mdcomp 3 | url = https://github.com/flamewing/mdcomp 4 | [submodule "FW-KENSC-ShellExt/boost/mpl"] 5 | path = FW-KENSC-ShellExt/boost/mpl 6 | url = https://github.com/boostorg/mpl/ 7 | [submodule "FW-KENSC-ShellExt/boost/config"] 8 | path = FW-KENSC-ShellExt/boost/config 9 | url = https://github.com/boostorg/config 10 | [submodule "FW-KENSC-ShellExt/boost/preprocessor"] 11 | path = FW-KENSC-ShellExt/boost/preprocessor 12 | url = https://github.com/boostorg/preprocessor 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.29.6) 2 | 3 | project(FW-KENSC_ShellExt LANGUAGES CXX) 4 | 5 | add_library(FW-KENSC-ShellExt SHARED 6 | "FW-KENSC-ShellExt/ClassFactory.cpp" 7 | "FW-KENSC-ShellExt/ContextMenu.cpp" 8 | "FW-KENSC-ShellExt/dllmain.cpp" 9 | "FW-KENSC-ShellExt/mdcomp/src/lib/comper.cc" 10 | "FW-KENSC-ShellExt/mdcomp/src/lib/enigma.cc" 11 | "FW-KENSC-ShellExt/mdcomp/src/lib/kosinski.cc" 12 | "FW-KENSC-ShellExt/mdcomp/src/lib/kosplus.cc" 13 | "FW-KENSC-ShellExt/mdcomp/src/lib/nemesis.cc" 14 | "FW-KENSC-ShellExt/mdcomp/src/lib/rocket.cc" 15 | "FW-KENSC-ShellExt/mdcomp/src/lib/saxman.cc" 16 | "FW-KENSC-ShellExt/Twizzler/Twizzler.cpp" 17 | ) 18 | 19 | target_compile_definitions(FW-KENSC-ShellExt PRIVATE "UNICODE=1" "_UNICODE=1") 20 | target_link_libraries(FW-KENSC-ShellExt PRIVATE shlwapi) 21 | target_include_directories(FW-KENSC-ShellExt PRIVATE "FW-KENSC-ShellExt/mdcomp/include") 22 | target_include_directories(FW-KENSC-ShellExt PRIVATE "FW-KENSC-ShellExt/boost/config/include") 23 | target_include_directories(FW-KENSC-ShellExt PRIVATE "FW-KENSC-ShellExt/boost/mpl/include") 24 | target_include_directories(FW-KENSC-ShellExt PRIVATE "FW-KENSC-ShellExt/boost/preprocessor/include") 25 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt.iss: -------------------------------------------------------------------------------- 1 | ; Script generated by the Inno Setup Script Wizard. 2 | ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! 3 | 4 | [Setup] 5 | ; NOTE: The value of AppId uniquely identifies this application. 6 | ; Do not use the same AppId value in installers for other applications. 7 | ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) 8 | AppId={{2D45BECF-09BF-42A8-9ED2-1BFC6B197F07} 9 | AppName=FW-KENSC 10 | AppVersion=1.3 11 | ;AppVerName=FW-KENSC 1.0 12 | AppPublisher=Sonic Retro 13 | AppPublisherURL=http://sonicretro.org/ 14 | AppSupportURL=http://sonicretro.org/ 15 | AppUpdatesURL=http://sonicretro.org/ 16 | DefaultDirName={pf}\FW-KENSC 17 | AllowNoIcons=yes 18 | OutputBaseFilename=FW-KENSC-setup-1.3 19 | Compression=lzma 20 | SolidCompression=yes 21 | ArchitecturesInstallIn64BitMode=x64 22 | 23 | [Languages] 24 | Name: "english"; MessagesFile: "compiler:Default.isl" 25 | 26 | [Files] 27 | Check: Is64BitInstallMode; Source: "x64\Release\FW-KENSC-ShellExt.dll"; DestDir: "{app}"; DestName: "FW-KENSC-ShellExt64.dll"; Flags: ignoreversion 28 | Check: Is64BitInstallMode; Source: "x64\Release\FW-KENSC-ShellExt.pdb"; DestDir: "{app}"; DestName: "FW-KENSC-ShellExt64.pdb"; Flags: ignoreversion 29 | Source: "Release\FW-KENSC-ShellExt.dll"; DestDir: "{app}"; DestName: "FW-KENSC-ShellExt.dll"; Flags: ignoreversion 30 | Source: "Release\FW-KENSC-ShellExt.pdb"; DestDir: "{app}"; DestName: "FW-KENSC-ShellExt.pdb"; Flags: ignoreversion 31 | ; NOTE: Don't use "Flags: ignoreversion" on any shared system files 32 | 33 | [Registry] 34 | Root: HKCR; Subkey: "*\shellex\ContextMenuHandlers\FW-KENSC"; ValueType: string; ValueData: "{{76F76F87-9DA0-48D6-9277-238FCEC133CA}"; Flags: uninsdeletekey 35 | Root: HKCR32; Subkey: "CLSID\{{76F76F87-9DA0-48D6-9277-238FCEC133CA}"; ValueType: string; ValueData: "FW-KENSC"; Flags: uninsdeletekey 36 | Root: HKCR32; Subkey: "CLSID\{{76F76F87-9DA0-48D6-9277-238FCEC133CA}\InProcServer32"; ValueType: string; ValueData: "{app}\FW-KENSC-ShellExt.dll" 37 | Root: HKCR32; Subkey: "CLSID\{{76F76F87-9DA0-48D6-9277-238FCEC133CA}\InProcServer32"; ValueType: string; ValueName: "ThreadingModel"; ValueData: "Apartment" 38 | Check: Is64BitInstallMode; Root: HKCR64; Subkey: "CLSID\{{76F76F87-9DA0-48D6-9277-238FCEC133CA}"; ValueType: string; ValueData: "FW-KENSC"; Flags: uninsdeletekey 39 | Check: Is64BitInstallMode; Root: HKCR64; Subkey: "CLSID\{{76F76F87-9DA0-48D6-9277-238FCEC133CA}\InProcServer32"; ValueType: string; ValueData: "{app}\FW-KENSC-ShellExt64.dll" 40 | Check: Is64BitInstallMode; Root: HKCR64; Subkey: "CLSID\{{76F76F87-9DA0-48D6-9277-238FCEC133CA}\InProcServer32"; ValueType: string; ValueName: "ThreadingModel"; ValueData: "Apartment" 41 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FW-KENSC-ShellExt", "FW-KENSC-ShellExt\FW-KENSC-ShellExt.vcxproj", "{3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Debug|x64 = Debug|x64 12 | Release|Win32 = Release|Win32 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Debug|Win32.ActiveCfg = Debug|Win32 17 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Debug|Win32.Build.0 = Debug|Win32 18 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Debug|x64.ActiveCfg = Debug|x64 19 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Debug|x64.Build.0 = Debug|x64 20 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Release|Win32.ActiveCfg = Release|Win32 21 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Release|Win32.Build.0 = Release|Win32 22 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Release|x64.ActiveCfg = Release|x64 23 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/ClassFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include "ClassFactory.h" 3 | #include "ContextMenu.h" 4 | #include 5 | #include 6 | 7 | extern long g_cDllRef; 8 | 9 | CClassFactory::CClassFactory() : m_cRef(1) 10 | { 11 | InterlockedIncrement(&g_cDllRef); 12 | } 13 | 14 | 15 | CClassFactory::~CClassFactory() 16 | { 17 | InterlockedDecrement(&g_cDllRef); 18 | } 19 | 20 | // IUnknown 21 | 22 | IFACEMETHODIMP CClassFactory::QueryInterface(REFIID riid, void **ppv) 23 | { 24 | static const QITAB qit[] = 25 | { 26 | QITABENT(CClassFactory, IClassFactory), 27 | { 0 }, 28 | }; 29 | return QISearch(this, qit, riid, ppv); 30 | } 31 | 32 | IFACEMETHODIMP_(ULONG) CClassFactory::AddRef() 33 | { 34 | return InterlockedIncrement(&m_cRef); 35 | } 36 | 37 | IFACEMETHODIMP_(ULONG) CClassFactory::Release() 38 | { 39 | ULONG cRef = InterlockedDecrement(&m_cRef); 40 | if (0 == cRef) 41 | { 42 | delete this; 43 | } 44 | return cRef; 45 | } 46 | 47 | // IClassFactory 48 | 49 | IFACEMETHODIMP CClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) 50 | { 51 | HRESULT hr = CLASS_E_NOAGGREGATION; 52 | 53 | if (pUnkOuter == NULL) 54 | { 55 | hr = E_OUTOFMEMORY; 56 | 57 | // Create the COM component. 58 | CContextMenu *pExt = new (std::nothrow) CContextMenu(); 59 | if (pExt) 60 | { 61 | // Query the specified interface. 62 | hr = pExt->QueryInterface(riid, ppvObject); 63 | pExt->Release(); 64 | } 65 | } 66 | 67 | return hr; 68 | } 69 | 70 | IFACEMETHODIMP CClassFactory::LockServer(BOOL fLock) 71 | { 72 | if (fLock) 73 | { 74 | InterlockedIncrement(&g_cDllRef); 75 | } 76 | else 77 | { 78 | InterlockedDecrement(&g_cDllRef); 79 | } 80 | return S_OK; 81 | } -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/ClassFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "unknwn.h" 3 | #include 4 | 5 | 6 | class CClassFactory : public IClassFactory 7 | { 8 | public: 9 | // IUnknown 10 | IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv); 11 | IFACEMETHODIMP_(ULONG) AddRef(); 12 | IFACEMETHODIMP_(ULONG) Release(); 13 | 14 | // IClassFactory 15 | IFACEMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv); 16 | IFACEMETHODIMP LockServer(BOOL fLock); 17 | 18 | CClassFactory(); 19 | 20 | protected: 21 | ~CClassFactory(); 22 | 23 | private: 24 | long m_cRef; 25 | }; -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/ContextMenu.cpp: -------------------------------------------------------------------------------- 1 | #include "StdAfx.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "ContextMenu.h" 8 | #include "mdcomp/kosinski.hh" 9 | #include "mdcomp/enigma.hh" 10 | #include "mdcomp/nemesis.hh" 11 | #include "mdcomp/saxman.hh" 12 | #include "mdcomp/comper.hh" 13 | #include "mdcomp/rocket.hh" 14 | #include "mdcomp/kosplus.hh" 15 | #include "Twizzler/Twizzler.h" 16 | 17 | using std::ifstream; 18 | using std::fstream; 19 | 20 | extern HINSTANCE g_hInst; 21 | extern long g_cDllRef; 22 | 23 | LPCTSTR fileextentions[] = { 24 | TEXT(".kos"), 25 | TEXT(".kosm"), 26 | TEXT(".eni"), 27 | TEXT(".nem"), 28 | TEXT(".sax"), 29 | TEXT(".sax"), 30 | TEXT(".comp"), 31 | TEXT(".compm"), 32 | TEXT(".rock"), 33 | TEXT(".rockm"), 34 | TEXT(".kosp"), 35 | TEXT(".kospm"), 36 | TEXT(".twiz"), 37 | TEXT(".twim") 38 | }; 39 | 40 | struct iteminfo { int id; LPCTSTR text; iteminfo *subitems; }; 41 | 42 | int curid = 0; 43 | 44 | // For some fucking reason options can't share a name or Windows 45 | // will call InvokeCommand with the ID of the *first* one 46 | // ...but only when you select a lot of files. 47 | // I have absolutely no clue why this happens. 48 | #define defaultmenu(name, format) iteminfo name##menu[] = { \ 49 | { curid++, format TEXT(" - &Decompress") }, \ 50 | { curid++, format TEXT(" - &Compress") }, \ 51 | { -1 } \ 52 | } 53 | 54 | #define moduledmenu(name, format) iteminfo name##menu[] = { \ 55 | { curid++, format TEXT(" - &Decompress") }, \ 56 | { curid++, format TEXT(" - &Compress") }, \ 57 | { curid++, TEXT("&Moduled ") format TEXT(" - Decompress") }, \ 58 | { curid++, TEXT("M&oduled ") format TEXT(" - Compress") }, \ 59 | { -1 } \ 60 | } 61 | 62 | moduledmenu(kos, TEXT("Kosinski")); 63 | defaultmenu(eni, TEXT("Enigma")); 64 | defaultmenu(nem, TEXT("Nemesis")); 65 | iteminfo saxmenu[] = { 66 | { curid++, TEXT("Saxman - &Decompress") }, 67 | { curid++, TEXT("Saxman - &Compress") }, 68 | { curid++, TEXT("Saxman - Decompress (&No Size)") }, 69 | { curid++, TEXT("Saxman - Compress (N&o Size)") }, 70 | { -1 } 71 | }; 72 | moduledmenu(comp, TEXT("Comper")); 73 | moduledmenu(rock, TEXT("Rocket")); 74 | moduledmenu(kosp, TEXT("Kosinski+")); 75 | 76 | const int END_OF_FW_KENSC = curid; 77 | 78 | moduledmenu(twiz, TEXT("Twizzler")); 79 | 80 | int maxid = curid; 81 | 82 | iteminfo rootmenu[] = { 83 | { curid++, TEXT("&Kosinski"), kosmenu }, 84 | { curid++, TEXT("&Enigma"), enimenu }, 85 | { curid++, TEXT("&Nemesis"), nemmenu }, 86 | { curid++, TEXT("&Saxman"), saxmenu }, 87 | { curid++, TEXT("&Comper"), compmenu }, 88 | { curid++, TEXT("&Rocket"), rockmenu }, 89 | { curid++, TEXT("Kosinski+"), kospmenu }, 90 | { curid++, TEXT("&Twizzler"), twizmenu }, 91 | { -1 } 92 | }; 93 | 94 | LPTSTR chgext(LPCTSTR name, LPCTSTR ext) 95 | { 96 | LPTSTR result = new TCHAR[MAX_PATH]; 97 | _tcscpy(result, name); 98 | PathRenameExtension(result, ext); 99 | return result; 100 | } 101 | 102 | void do_compression_decompression(const int mode, LPCTSTR in) 103 | { 104 | const LPCTSTR out = chgext(in, (mode & 1) ? fileextentions[mode / 2] : TEXT(".unc")); 105 | 106 | // FW-KENSC and Twizzler have different ways of being called 107 | if (mode < END_OF_FW_KENSC) 108 | { 109 | ifstream instr(in, std::ios::in | std::ios::binary); 110 | fstream outstr(out, std::ios::in | std::ios::out | std::ios::binary | std::ios::trunc); 111 | delete[] out; 112 | switch (mode) 113 | { 114 | // Kosinski 115 | case 0: 116 | { 117 | kosinski::decode(instr, outstr); 118 | break; 119 | } 120 | case 1: 121 | { 122 | kosinski::encode(instr, outstr); 123 | break; 124 | } 125 | case 2: 126 | { 127 | kosinski::moduled_decode(instr, outstr); 128 | break; 129 | } 130 | case 3: 131 | { 132 | kosinski::moduled_encode(instr, outstr); 133 | break; 134 | } 135 | // Enigma 136 | case 4: 137 | { 138 | enigma::decode(instr, outstr); 139 | break; 140 | } 141 | case 5: 142 | { 143 | enigma::encode(instr, outstr); 144 | break; 145 | } 146 | // Nemesis 147 | case 6: 148 | { 149 | nemesis::decode(instr, outstr); 150 | break; 151 | } 152 | case 7: 153 | { 154 | nemesis::encode(instr, outstr); 155 | break; 156 | } 157 | // Saxman 158 | case 8: 159 | { 160 | saxman::decode(instr, outstr); 161 | break; 162 | } 163 | case 9: 164 | { 165 | saxman::encode(instr, outstr, true); 166 | break; 167 | } 168 | // Saxman (no size) 169 | case 10: 170 | { 171 | instr.seekg(0, ifstream::end); 172 | auto size = instr.tellg(); 173 | instr.seekg(0); 174 | saxman::decode(instr, outstr, size); 175 | break; 176 | } 177 | case 11: 178 | { 179 | saxman::encode(instr, outstr, false); 180 | break; 181 | } 182 | // Comper 183 | case 12: 184 | { 185 | comper::decode(instr, outstr); 186 | break; 187 | } 188 | case 13: 189 | { 190 | comper::encode(instr, outstr); 191 | break; 192 | } 193 | case 14: 194 | { 195 | comper::moduled_decode(instr, outstr); 196 | break; 197 | } 198 | case 15: 199 | { 200 | comper::moduled_encode(instr, outstr); 201 | break; 202 | } 203 | // Rocket 204 | case 16: 205 | { 206 | rocket::decode(instr, outstr); 207 | break; 208 | } 209 | case 17: 210 | { 211 | rocket::encode(instr, outstr); 212 | break; 213 | } 214 | case 18: 215 | { 216 | rocket::moduled_decode(instr, outstr); 217 | break; 218 | } 219 | case 19: 220 | { 221 | rocket::moduled_encode(instr, outstr); 222 | break; 223 | } 224 | // Kosinski+ 225 | case 20: 226 | { 227 | kosplus::decode(instr, outstr); 228 | break; 229 | } 230 | case 21: 231 | { 232 | kosplus::encode(instr, outstr); 233 | break; 234 | } 235 | case 22: 236 | { 237 | kosplus::moduled_decode(instr, outstr); 238 | break; 239 | } 240 | case 23: 241 | { 242 | kosplus::moduled_encode(instr, outstr); 243 | break; 244 | } 245 | } 246 | } 247 | else 248 | { 249 | FILE *infile = _tfopen(in, TEXT("rb")); 250 | fseek(infile, 0, SEEK_END); 251 | int filesize = ftell(infile); 252 | rewind(infile); 253 | char *buffer = (char*)malloc(filesize); 254 | fread(buffer, 1, filesize, infile); 255 | fclose(infile); 256 | 257 | switch (mode) 258 | { 259 | case 24: 260 | case 26: 261 | { 262 | TwizDec(buffer, filesize); 263 | break; 264 | } 265 | case 25: 266 | { 267 | TwizComp(buffer, filesize); 268 | break; 269 | } 270 | case 27: 271 | { 272 | TwizComp(buffer, filesize, true, 0x1000); 273 | break; 274 | } 275 | } 276 | 277 | FILE *outfile = _tfopen(out, TEXT("wb")); 278 | delete[] out; 279 | fwrite(buffer, 1, filesize, outfile); 280 | free(buffer); 281 | fclose(outfile); 282 | } 283 | } 284 | 285 | CContextMenu::CContextMenu(void) : m_cRef(1) 286 | { 287 | InterlockedIncrement(&g_cDllRef); 288 | } 289 | 290 | CContextMenu::~CContextMenu(void) 291 | { 292 | InterlockedDecrement(&g_cDllRef); 293 | } 294 | 295 | // IUnknown 296 | 297 | IFACEMETHODIMP CContextMenu::QueryInterface(REFIID riid, void **ppv) 298 | { 299 | static const QITAB qit[] = 300 | { 301 | QITABENT(CContextMenu, IContextMenu), 302 | QITABENT(CContextMenu, IShellExtInit), 303 | { 0 }, 304 | }; 305 | return QISearch(this, qit, riid, ppv); 306 | } 307 | 308 | IFACEMETHODIMP_(ULONG) CContextMenu::AddRef() 309 | { 310 | return InterlockedIncrement(&m_cRef); 311 | } 312 | 313 | IFACEMETHODIMP_(ULONG) CContextMenu::Release() 314 | { 315 | ULONG cRef = InterlockedDecrement(&m_cRef); 316 | if (cRef == 0) 317 | delete this; 318 | 319 | return cRef; 320 | } 321 | 322 | 323 | // IShellExtInit 324 | 325 | IFACEMETHODIMP CContextMenu::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hKeyProgID) 326 | { 327 | if (pDataObj == NULL) 328 | return E_INVALIDARG; 329 | 330 | HRESULT hr = E_FAIL; 331 | 332 | FORMATETC fe = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 333 | STGMEDIUM stm; 334 | 335 | // The pDataObj pointer contains the objects being acted upon. In this 336 | // example, we get an HDROP handle for enumerating the selected files and 337 | // folders. 338 | if (SUCCEEDED(pDataObj->GetData(&fe, &stm))) 339 | { 340 | // Get an HDROP handle. 341 | HDROP hDrop = static_cast(GlobalLock(stm.hGlobal)); 342 | if (hDrop != NULL) 343 | { 344 | // Determine how many files are involved in this operation. This 345 | // code sample displays the custom context menu item when only 346 | // one file is selected. 347 | UINT nFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); 348 | TCHAR buf[MAX_PATH]; 349 | for (unsigned int i = 0; i < nFiles; i++) 350 | // Get the path of the file. 351 | if (DragQueryFile(hDrop, i, buf, MAX_PATH) != 0) 352 | selectedFiles.push_back(buf); 353 | else 354 | return hr; 355 | hr = S_OK; 356 | 357 | GlobalUnlock(stm.hGlobal); 358 | } 359 | 360 | ReleaseStgMedium(&stm); 361 | } 362 | 363 | // If any value other than S_OK is returned from the method, the context 364 | // menu item is not displayed. 365 | return hr; 366 | } 367 | 368 | // IContextMenu 369 | 370 | HMENU ProcessSubMenu(iteminfo *info, UINT idCmdFirst) 371 | { 372 | HMENU hSubmenu = CreatePopupMenu(); 373 | 374 | int i = 0; 375 | while (info[i].id != -1) 376 | { 377 | MENUITEMINFO mii = { sizeof(MENUITEMINFO) }; 378 | mii.fMask = MIIM_STRING | MIIM_ID; 379 | mii.wID = info[i].id + idCmdFirst; 380 | mii.dwTypeData = const_cast(info[i].text); 381 | if (info[i].subitems != nullptr) 382 | { 383 | mii.fMask |= MIIM_SUBMENU; 384 | mii.hSubMenu = ProcessSubMenu(info[i].subitems, idCmdFirst); 385 | } 386 | InsertMenuItem(hSubmenu, i++, TRUE, &mii); 387 | } 388 | return hSubmenu; 389 | } 390 | 391 | IFACEMETHODIMP CContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) 392 | { 393 | // If uFlags include CMF_DEFAULTONLY then we should not do anything. 394 | if (CMF_DEFAULTONLY & uFlags) 395 | return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0)); 396 | 397 | MENUITEMINFO mii = { sizeof(mii) }; 398 | mii.fMask = MIIM_STRING | MIIM_ID | MIIM_SUBMENU; 399 | mii.wID = idCmdFirst + curid; 400 | mii.dwTypeData = const_cast(TEXT("FW-KENSC")); 401 | mii.hSubMenu = ProcessSubMenu(rootmenu, idCmdFirst); 402 | if (!InsertMenuItem(hMenu, indexMenu, TRUE, &mii)) 403 | { 404 | return HRESULT_FROM_WIN32(GetLastError()); 405 | } 406 | 407 | // Return an HRESULT value with the severity set to SEVERITY_SUCCESS. 408 | // Set the code value to the offset of the largest command identifier 409 | // that was assigned, plus one (1). 410 | return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(curid + 1)); 411 | } 412 | 413 | IFACEMETHODIMP CContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO pici) 414 | { 415 | bool fUnicode = pici->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && pici->fMask & CMIC_MASK_UNICODE; 416 | 417 | void *ptr; 418 | 419 | if (fUnicode) 420 | ptr = (void *)((CMINVOKECOMMANDINFOEX *)pici)->lpVerbW; 421 | else 422 | ptr = (void *)pici->lpVerb; 423 | 424 | if (HIWORD(ptr) != 0) 425 | return E_INVALIDARG; 426 | 427 | // Is the command identifier offset supported by this context menu 428 | // extension? 429 | if (LOWORD(pici->lpVerb) < maxid) 430 | for (auto i = selectedFiles.begin(); i != selectedFiles.end(); i++) 431 | do_compression_decompression(LOWORD(pici->lpVerb), (*i).c_str()); 432 | else 433 | return E_FAIL; 434 | return S_OK; 435 | } 436 | 437 | IFACEMETHODIMP CContextMenu::GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax) 438 | { 439 | return E_INVALIDARG; 440 | } -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/ContextMenu.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | class CContextMenu : public IShellExtInit, public IContextMenu 7 | { 8 | public: 9 | // IUnknown 10 | IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv); 11 | IFACEMETHODIMP_(ULONG) AddRef(); 12 | IFACEMETHODIMP_(ULONG) Release(); 13 | 14 | // IShellExtInit 15 | IFACEMETHODIMP Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hKeyProgID); 16 | 17 | // IContextMenu 18 | IFACEMETHODIMP QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); 19 | IFACEMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO pici); 20 | IFACEMETHODIMP GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax); 21 | 22 | CContextMenu(void); 23 | 24 | protected: 25 | ~CContextMenu(void); 26 | 27 | private: 28 | // Reference count of component. 29 | long m_cRef; 30 | 31 | std::vector> selectedFiles; 32 | }; -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/FW-KENSC-ShellExt.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | DllGetClassObject PRIVATE 3 | DllCanUnloadNow PRIVATE 4 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/FW-KENSC-ShellExt.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {3C47FFF4-F6EE-4B30-8DE8-979401A53B8B} 23 | Win32Proj 24 | FWKENSCShellExt 25 | 26 | 27 | 28 | DynamicLibrary 29 | true 30 | v141_xp 31 | Unicode 32 | 33 | 34 | DynamicLibrary 35 | true 36 | v141_xp 37 | Unicode 38 | 39 | 40 | DynamicLibrary 41 | false 42 | v141_xp 43 | true 44 | Unicode 45 | 46 | 47 | DynamicLibrary 48 | false 49 | v141_xp 50 | true 51 | Unicode 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | true 71 | 72 | 73 | true 74 | 75 | 76 | false 77 | 78 | 79 | false 80 | 81 | 82 | 83 | Use 84 | Level3 85 | Disabled 86 | WIN32;_DEBUG;_WINDOWS;_USRDLL;FWKENSCSHELLEXT_EXPORTS;%(PreprocessorDefinitions) 87 | $(ProjectDir)\boost\mpl\include;$(ProjectDir)\boost\preprocessor\include;$(ProjectDir)\boost\config\include;$(ProjectDir)\mdcomp\include;%(AdditionalIncludeDirectories) 88 | 89 | 90 | Windows 91 | true 92 | $(TargetName).def 93 | shlwapi.lib;%(AdditionalDependencies) 94 | 95 | 96 | 97 | 98 | Use 99 | Level3 100 | Disabled 101 | WIN32;_DEBUG;_WINDOWS;_USRDLL;FWKENSCSHELLEXT_EXPORTS;%(PreprocessorDefinitions) 102 | $(ProjectDir)\boost\mpl\include;$(ProjectDir)\boost\preprocessor\include;$(ProjectDir)\boost\config\include;$(ProjectDir)\mdcomp\include;%(AdditionalIncludeDirectories) 103 | 104 | 105 | Windows 106 | true 107 | $(TargetName).def 108 | shlwapi.lib;%(AdditionalDependencies) 109 | 110 | 111 | 112 | 113 | Level3 114 | Use 115 | MaxSpeed 116 | true 117 | true 118 | WIN32;NDEBUG;_WINDOWS;_USRDLL;FWKENSCSHELLEXT_EXPORTS;%(PreprocessorDefinitions) 119 | 120 | 121 | $(ProjectDir)\boost\mpl\include;$(ProjectDir)\boost\preprocessor\include;$(ProjectDir)\boost\config\include;$(ProjectDir)\mdcomp\include;%(AdditionalIncludeDirectories) 122 | 123 | 124 | Windows 125 | true 126 | true 127 | true 128 | $(TargetName).def 129 | shlwapi.lib;%(AdditionalDependencies) 130 | 131 | 132 | 133 | 134 | Level3 135 | Use 136 | MaxSpeed 137 | true 138 | true 139 | WIN32;NDEBUG;_WINDOWS;_USRDLL;FWKENSCSHELLEXT_EXPORTS;%(PreprocessorDefinitions) 140 | $(ProjectDir)\boost\mpl\include;$(ProjectDir)\boost\preprocessor\include;$(ProjectDir)\boost\config\include;$(ProjectDir)\mdcomp\include;%(AdditionalIncludeDirectories) 141 | 142 | 143 | Windows 144 | true 145 | true 146 | true 147 | $(TargetName).def 148 | shlwapi.lib;%(AdditionalDependencies) 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | false 178 | false 179 | Use 180 | Use 181 | false 182 | false 183 | Use 184 | Use 185 | 186 | 187 | NotUsing 188 | NotUsing 189 | NotUsing 190 | NotUsing 191 | 192 | 193 | NotUsing 194 | NotUsing 195 | NotUsing 196 | NotUsing 197 | 198 | 199 | NotUsing 200 | NotUsing 201 | NotUsing 202 | NotUsing 203 | 204 | 205 | NotUsing 206 | NotUsing 207 | NotUsing 208 | NotUsing 209 | 210 | 211 | NotUsing 212 | NotUsing 213 | NotUsing 214 | NotUsing 215 | 216 | 217 | NotUsing 218 | NotUsing 219 | NotUsing 220 | NotUsing 221 | 222 | 223 | NotUsing 224 | NotUsing 225 | NotUsing 226 | NotUsing 227 | 228 | 229 | Create 230 | Create 231 | Create 232 | Create 233 | 234 | 235 | NotUsing 236 | NotUsing 237 | NotUsing 238 | NotUsing 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/FW-KENSC-ShellExt.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | Header Files 62 | 63 | 64 | Header Files 65 | 66 | 67 | Header Files 68 | 69 | 70 | Header Files 71 | 72 | 73 | 74 | 75 | Source Files 76 | 77 | 78 | Source Files 79 | 80 | 81 | Source Files 82 | 83 | 84 | Source Files 85 | 86 | 87 | Source Files 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files 103 | 104 | 105 | Source Files 106 | 107 | 108 | Source Files 109 | 110 | 111 | 112 | 113 | Source Files 114 | 115 | 116 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : FW-KENSC-ShellExt Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this FW-KENSC-ShellExt DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your FW-KENSC-ShellExt application. 9 | 10 | 11 | FW-KENSC-ShellExt.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | FW-KENSC-ShellExt.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | FW-KENSC-ShellExt.cpp 25 | This is the main DLL source file. 26 | 27 | When created, this DLL does not export any symbols. As a result, it 28 | will not produce a .lib file when it is built. If you wish this project 29 | to be a project dependency of some other project, you will either need to 30 | add code to export some symbols from the DLL so that an export library 31 | will be produced, or you can set the Ignore Input Library property to Yes 32 | on the General propert page of the Linker folder in the project's Property 33 | Pages dialog box. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | Other standard files: 37 | 38 | StdAfx.h, StdAfx.cpp 39 | These files are used to build a precompiled header (PCH) file 40 | named FW-KENSC-ShellExt.pch and a precompiled types file named StdAfx.obj. 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | Other notes: 44 | 45 | AppWizard uses "TODO:" comments to indicate parts of the source code you 46 | should add to or customize. 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/Twizzler/Twizzler.cpp: -------------------------------------------------------------------------------- 1 | extern "C" 2 | { 3 | 4 | #include 5 | #include 6 | 7 | unsigned long __inline clz(unsigned long value) 8 | { 9 | unsigned long leading_zero = 0; 10 | 11 | if (_BitScanReverse(&leading_zero, value)) 12 | { 13 | return 31 - leading_zero; 14 | } 15 | else 16 | { 17 | // Same remarks as above 18 | return 32; 19 | } 20 | } 21 | 22 | // ============================================================================= 23 | // ----------------------------------------------------------------------------- 24 | // Twizzler 25 | // ----------------------------------------------------------------------------- 26 | // Start-{0-U-U-U-U-U-U-U-U----------------------------------------------------------------------------------}-Repeat 27 | // \1{0-S-S-S-S-R-R-R-R-R-R-R-R-R-R-R-R-R-R-R-R-(9-10007)}-{0-C-(2-3)----------------------------------| 28 | // \1{0-R-R-R-(1-8)------------------------------------| \1{C-C-(4-6)--------------------------------| 29 | // \1-H-H-H-H-H-H-H-H-H-H-H-H-H-H-H-H-H-H-(R)--------/ \1-1{1{C-C-C-(7-D)------------------------| 30 | // | \1-1-1{1{C-C-C-C-(E-1C)-------------| 31 | // | | \1-1-1-1-C-C-C-C-C-(1D-3C)--| 32 | // | \0-C-C-C-C-C-C-C-C-C-(3D-23C)-| 33 | // \0-H-H-H-H-H-H-H-H-H-H-H-H-(C)--------/ 34 | // ----------------------------------------------------------------------------- 35 | 36 | #define rangeof(ENTRY) (0x01<<(0x08*sizeof(ENTRY))) 37 | 38 | #define COPY_MIN 0x02 39 | #define COPY_EXT 0x3D 40 | #define COPY_MAX (COPY_EXT + 0x1FF) 41 | #define RETRACE_SHORT 0x08 42 | #define RETRACE_DIST 0xFFFF 43 | #define RETRACE_MAX (RETRACE_DIST + RETRACE_SHORT) 44 | #define WINDOW_SIZE (0x10000 * 0x02) 45 | #define WINDOW_WRAP (WINDOW_SIZE - 0x01) 46 | #define HUFFRET_BITSIZE (0x12 - 0x01) 47 | #define HUFFCOPY_BITSIZE (0x0C - 0x01) 48 | 49 | // ----------------------------------------------------------------------------- 50 | // Routine macros 51 | // ----------------------------------------------------------------------------- 52 | 53 | #define SAVEFIELD(BField,BCount,BLoc,BNextLoc,BSize)\ 54 | {\ 55 | if (--BCount == 0x00)\ 56 | {\ 57 | *BLoc = BField;\ 58 | BLoc = BNextLoc++;\ 59 | BSize++;\ 60 | BField = 0x00;\ 61 | BCount = 0x08;\ 62 | }\ 63 | } 64 | 65 | #define CLEARBIT(BField,BCount,BLoc,BNextLoc,BSize)\ 66 | {\ 67 | SAVEFIELD (BField, BCount, BLoc, BNextLoc, BSize);\ 68 | BField <<= 0x01;\ 69 | } 70 | 71 | #define SETBIT(BField,BCount,BLoc,BNextLoc,BSize)\ 72 | {\ 73 | SAVEFIELD (BField, BCount, BLoc, BNextLoc, BSize);\ 74 | BField = (BField << 0x01) | 0x01;\ 75 | } 76 | 77 | #define PLACEBIT(BValue,BField,BCount,BLoc,BNextLoc,BSize)\ 78 | {\ 79 | SAVEFIELD (BField, BCount, BLoc, BNextLoc, BSize);\ 80 | BField = (BField << 0x01) | ((BValue) & 0x01);\ 81 | } 82 | 83 | #define GETBIT(BValue,BField,BCount,BNextLoc)\ 84 | {\ 85 | if (--BCount == 0x00)\ 86 | {\ 87 | BField = *BNextLoc++;\ 88 | BCount = 0x08;\ 89 | }\ 90 | BValue = (BValue << 0x01) | ((BField >> 0x07) & 0x01);\ 91 | BField <<= 0x01;\ 92 | } 93 | 94 | #define TwizAlloc(TYPE,Pointer,Size)\ 95 | {\ 96 | do\ 97 | {\ 98 | Pointer = (TYPE) malloc (Size);\ 99 | }\ 100 | while (Pointer == NULL);\ 101 | } 102 | 103 | #define TwizAllZZ(TYPE,Pointer,Size)\ 104 | {\ 105 | TwizAlloc (TYPE, Pointer, Size);\ 106 | memset (Pointer, 0x00, Size);\ 107 | } 108 | 109 | // ----------------------------------------------------------------------------- 110 | // Lookup Tables 111 | // ----------------------------------------------------------------------------- 112 | 113 | // --- Number of bits that are lost from "SavedCur" depending on copy type --- 114 | 115 | static const int SavedCopies [] = { 0x00, 0x00, // Invalid/Padding 116 | 117 | 0x01, 0x01, // Short copy - 0C 118 | 119 | 0x02, 0x02, 0x02, // Distant copy - 1CC 120 | 121 | 0x06, 0x06, 0x06, 0x06, // Distant copy - 1111CCC 122 | 0x06, 0x06, 0x06, 123 | 124 | 0x0B, 0x0B, 0x0B, 0x0B, // Distant copy - 11111111CCCC 125 | 0x0B, 0x0B, 0x0B, 0x0B, 126 | 0x0B, 0x0B, 0x0B, 0x0B, 127 | 0x0B, 0x0B, 0x0B, 128 | 129 | 0x10, 0x10, 0x10, 0x10, // Distant copy - 111111111111CCCCC 130 | 0x10, 0x10, 0x10, 0x10, 131 | 0x10, 0x10, 0x10, 0x10, 132 | 0x10, 0x10, 0x10, 0x10, 133 | 0x10, 0x10, 0x10, 0x10, 134 | 0x10, 0x10, 0x10, 0x10, 135 | 0x10, 0x10, 0x10, 0x10, 136 | 0x10, 0x10, 0x10, 0x10, 137 | 138 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // Extended copy - 11111110CCCCCCCCC 139 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 140 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 141 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 142 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 143 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 144 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 145 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 146 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 147 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 148 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 149 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 150 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 151 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 152 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 153 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 154 | 155 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 156 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 157 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 158 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 159 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 160 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 161 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 162 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 163 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 164 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 165 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 166 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 167 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 168 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 169 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 170 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 171 | 172 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 173 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 174 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 175 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 176 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 177 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 178 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 179 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 180 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 181 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 182 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 183 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 184 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 185 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 186 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 187 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 188 | 189 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 190 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 191 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 192 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 193 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 194 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 195 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 196 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 197 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 198 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 199 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 200 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 201 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 202 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 203 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 204 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 205 | 206 | }; 207 | 208 | // --- Subtracting "CopyCur" to minimum before saving --- 209 | 210 | static const int CopySubtract [] = { 0x00, 0x00, // Invalid/Padding 211 | 212 | 0x02, 0x02, // Short copy - 0C 213 | 214 | 0x04, 0x04, 0x04, // Distant copy - 1CC 215 | 216 | 0x07, 0x07, 0x07, 0x07, // Distant copy - 1111CCC 217 | 0x07, 0x07, 0x07, 218 | 219 | 0x0E, 0x0E, 0x0E, 0x0E, // Distant copy - 11111111CCCC 220 | 0x0E, 0x0E, 0x0E, 0x0E, 221 | 0x0E, 0x0E, 0x0E, 0x0E, 222 | 0x0E, 0x0E, 0x0E, 223 | 224 | 0x1D, 0x1D, 0x1D, 0x1D, // Distant copy - 111111111111CCCCC 225 | 0x1D, 0x1D, 0x1D, 0x1D, 226 | 0x1D, 0x1D, 0x1D, 0x1D, 227 | 0x1D, 0x1D, 0x1D, 0x1D, 228 | 0x1D, 0x1D, 0x1D, 0x1D, 229 | 0x1D, 0x1D, 0x1D, 0x1D, 230 | 0x1D, 0x1D, 0x1D, 0x1D, 231 | 0x1D, 0x1D, 0x1D, 0x1D, 232 | 233 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, // Extended copy - 11111110CCCCCCCCC 234 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 235 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 236 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 237 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 238 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 239 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 240 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 241 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 242 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 243 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 244 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 245 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 246 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 247 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 248 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 249 | 250 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 251 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 252 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 253 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 254 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 255 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 256 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 257 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 258 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 259 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 260 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 261 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 262 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 263 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 264 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 265 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 266 | 267 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 268 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 269 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 270 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 271 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 272 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 273 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 274 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 275 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 276 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 277 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 278 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 279 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 280 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 281 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 282 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 283 | 284 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 285 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 286 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 287 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 288 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 289 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 290 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 291 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 292 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 293 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 294 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 295 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 296 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 297 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 298 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 299 | 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D 300 | 301 | }; 302 | 303 | // --- Number of "1" bits to fill (see comments for example) --- 304 | 305 | static const int CopyBitFill [] = { 0x00, 0x00, // Invalid/Padding 306 | 307 | 0x00, 0x00, // Short copy - 0C 308 | 309 | 0x01, 0x01, 0x01, // Distant copy - 1CC 310 | 311 | 0x04, 0x04, 0x04, 0x04, // Distant copy - 1111CCC 312 | 0x04, 0x04, 0x04, 313 | 314 | 0x08, 0x08, 0x08, 0x08, // Distant copy - 11111111CCCC 315 | 0x08, 0x08, 0x08, 0x08, 316 | 0x08, 0x08, 0x08, 0x08, 317 | 0x08, 0x08, 0x08, 318 | 319 | 0x0C, 0x0C, 0x0C, 0x0C, // Distant copy - 111111111111CCCCC 320 | 0x0C, 0x0C, 0x0C, 0x0C, 321 | 0x0C, 0x0C, 0x0C, 0x0C, 322 | 0x0C, 0x0C, 0x0C, 0x0C, 323 | 0x0C, 0x0C, 0x0C, 0x0C, 324 | 0x0C, 0x0C, 0x0C, 0x0C, 325 | 0x0C, 0x0C, 0x0C, 0x0C, 326 | 0x0C, 0x0C, 0x0C, 0x0C, 327 | 328 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, // Extended copy - 11111110CCCCCCCCC 329 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, // Negative = placing 0 on the end 330 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 331 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 332 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 333 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 334 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 335 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 336 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 337 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 338 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 339 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 340 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 341 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 342 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 343 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 344 | 345 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 346 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 347 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 348 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 349 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 350 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 351 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 352 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 353 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 354 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 355 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 356 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 357 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 358 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 359 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 360 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 361 | 362 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 363 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 364 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 365 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 366 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 367 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 368 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 369 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 370 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 371 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 372 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 373 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 374 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 375 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 376 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 377 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 378 | 379 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 380 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 381 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 382 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 383 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 384 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 385 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 386 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 387 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 388 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 389 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 390 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 391 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 392 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 393 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, 394 | -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07, -0x07 395 | 396 | }; 397 | 398 | // --- Number of "C" bits to fill (see comments for example) --- 399 | 400 | static const int CopyBitCount [] = { 0x00, 0x00, // Invalid/Padding 401 | 402 | 0x01, 0x01, // Short copy - 0C 403 | 404 | 0x02, 0x02, 0x02, // Distant copy - 1CC 405 | 406 | 0x03, 0x03, 0x03, 0x03, // Distant copy - 1111CCC 407 | 0x03, 0x03, 0x03, 408 | 409 | 0x04, 0x04, 0x04, 0x04, // Distant copy - 11111111CCCC 410 | 0x04, 0x04, 0x04, 0x04, 411 | 0x04, 0x04, 0x04, 0x04, 412 | 0x04, 0x04, 0x04, 413 | 414 | 0x05, 0x05, 0x05, 0x05, // Distant copy - 111111111111CCCCC 415 | 0x05, 0x05, 0x05, 0x05, 416 | 0x05, 0x05, 0x05, 0x05, 417 | 0x05, 0x05, 0x05, 0x05, 418 | 0x05, 0x05, 0x05, 0x05, 419 | 0x05, 0x05, 0x05, 0x05, 420 | 0x05, 0x05, 0x05, 0x05, 421 | 0x05, 0x05, 0x05, 0x05, 422 | 423 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, // Extended copy - 11111110CCCCCCCCC 424 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 425 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 426 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 427 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 428 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 429 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 430 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 431 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 432 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 433 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 434 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 435 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 436 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 437 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 438 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 439 | 440 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 441 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 442 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 443 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 444 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 445 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 446 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 447 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 448 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 449 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 450 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 451 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 452 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 453 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 454 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 455 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 456 | 457 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 458 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 459 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 460 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 461 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 462 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 463 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 464 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 465 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 466 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 467 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 468 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 469 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 470 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 471 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 472 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 473 | 474 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 475 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 476 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 477 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 478 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 479 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 480 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 481 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 482 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 483 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 484 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 485 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 486 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 487 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 488 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 489 | 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09 490 | 491 | }; 492 | 493 | // ============================================================================= 494 | // ----------------------------------------------------------------------------- 495 | // Twizzler Compression Algorithm 496 | // ----------------------------------------------------------------------------- 497 | 498 | void TwizComp (char *&Input, int &InputSize, bool moduled = false, int module_size = 0) 499 | 500 | { 501 | const char *WindowCur, *RetraceCur; 502 | const char *InputAccess = Input; 503 | 504 | int WindowLoc = 0x00; 505 | int WindowPos; 506 | int WindowCopy; 507 | int WindowCount = InputSize; 508 | int InputLoc = 0x00; 509 | int InputCount = InputSize; 510 | int RetraceLoc; 511 | int RetracePos; 512 | int RetraceCount; 513 | int RetraceBest; 514 | int CopyCur; 515 | int CopyBest; 516 | int CopyTotal = COPY_MAX; 517 | int SavedCur; 518 | int SavedBest; 519 | int SavedTotal = 0x00; 520 | 521 | unsigned short *Document; 522 | unsigned short *DocuStore; 523 | int DocuSize = 0x00; 524 | 525 | int BinaryRange; 526 | const int *HuffReadOnly; 527 | 528 | int HuffRetLoc; 529 | int HuffRetSize; 530 | int HuffRetBest; 531 | const int *HuffRetOff; 532 | 533 | int HuffCopyLoc; 534 | int HuffCopySize; 535 | int HuffCopyBest; 536 | const int *HuffCopyOff; 537 | 538 | int OutputSize; 539 | char *Output; 540 | char *OutputAccess; 541 | 542 | int Count, Offset, ExtendSet = 0x00; 543 | unsigned short Word; 544 | char Byte; 545 | 546 | char *BitLoc; 547 | char BitField; 548 | char BitCount; 549 | 550 | int *RetStart; 551 | int *RetCount; 552 | int *Retraces; 553 | unsigned short *WindowWord; 554 | char *Window; 555 | 556 | int *HuffRetrace; 557 | int *HuffRetChain; 558 | 559 | int *HuffCopy; 560 | int *HuffCopyChain; 561 | 562 | TwizAlloc (int*, RetStart, rangeof (unsigned short) * sizeof (int)); 563 | TwizAllZZ (int*, RetCount, rangeof (unsigned short) * sizeof (int)); 564 | TwizAlloc (int*, Retraces, WINDOW_SIZE * sizeof (int)); 565 | TwizAlloc (unsigned short*, WindowWord, WINDOW_SIZE * sizeof (unsigned short)); 566 | TwizAlloc (char*, Window, (WINDOW_SIZE + (COPY_MAX + 0x01)) * sizeof (unsigned short)); 567 | TwizAllZZ (int*, HuffRetrace, (RETRACE_MAX + 0x01) * sizeof (int)); 568 | TwizAllZZ (int*, HuffCopy, (COPY_MAX + 0x01) * sizeof (int)); 569 | TwizAlloc (unsigned short*, DocuStore, (InputSize * 0x02) * sizeof (unsigned short)); 570 | 571 | // ----------------------------------------------------------------------------- 572 | // Main Search Loop 573 | // ----------------------------------------------------------------------------- 574 | 575 | Document = DocuStore; 576 | while (WindowCount > 0x00) 577 | { 578 | // --- Update Window --- 579 | 580 | WindowCopy = (COPY_MAX + 0x01) - (InputLoc - WindowLoc); 581 | if (WindowCopy > InputCount) 582 | { 583 | WindowCopy = InputCount; 584 | } 585 | while (WindowCopy > 0x00) 586 | { 587 | if (InputLoc >= WINDOW_SIZE) 588 | { 589 | Word = WindowWord [(InputLoc & WINDOW_WRAP)]; 590 | /* if (RetCount [Word] == 0x00) 591 | { 592 | printf ("Error; we've got a problem here...\n"); 593 | printf ("InputLoc: %X (WINDOW_WRAP: %X)\n", InputLoc, InputLoc & WINDOW_WRAP); 594 | printf ("Word: %0.4X\n", Word); 595 | printf ("WindowLoc: %X (WINDOW_WRAP: %X)\n", WindowLoc, WindowLoc & WINDOW_WRAP); 596 | fflush (stdin); 597 | getchar ( ); 598 | } */ 599 | RetCount [Word]--; 600 | } 601 | Byte = *InputAccess++; 602 | if ((InputLoc & WINDOW_WRAP) <= (COPY_MAX + 0x01)) 603 | { 604 | Window [(InputLoc & WINDOW_WRAP) + WINDOW_SIZE] = Byte; 605 | } 606 | Window [(InputLoc++ & WINDOW_WRAP)] = Byte; 607 | InputCount--; 608 | WindowCopy--; 609 | } 610 | 611 | // --- Retrace Search --- 612 | 613 | WindowPos = WindowLoc; 614 | Word = Window [(WindowPos++ & WINDOW_WRAP)] & 0xFF; 615 | Word |= Window [(WindowPos++ & WINDOW_WRAP)] << 0x08; 616 | RetraceLoc = RetStart [Word]; 617 | RetraceCount = RetCount [Word]; 618 | SavedBest = -0x01; CopyBest = 0x01; 619 | if (COPY_MAX > WindowCount) 620 | { 621 | CopyTotal = WindowCount; 622 | } 623 | 624 | while (RetraceLoc >= (WindowLoc - (moduled ? module_size : RETRACE_MAX)) && RetraceCount-- > 0x00) 625 | { 626 | WindowCur = Window + (WindowPos & WINDOW_WRAP); 627 | RetraceCur = Window + ((RetraceLoc + 0x02) & WINDOW_WRAP); 628 | CopyCur = COPY_MIN; 629 | while (*WindowCur++ == *RetraceCur++) 630 | { 631 | CopyCur++; 632 | if (CopyCur >= CopyTotal) 633 | { 634 | CopyCur = CopyTotal; 635 | break; 636 | } 637 | } 638 | if (CopyCur > CopyBest) 639 | { 640 | SavedCur = (CopyCur * 0x08) - 0x03; 641 | RetracePos = WindowLoc - RetraceLoc; 642 | 643 | // --- Retrace Check --- 644 | 645 | if (RetracePos <= RETRACE_SHORT) 646 | { 647 | SavedCur -= 3 + 1; 648 | } 649 | else 650 | { 651 | // It's OK to use "__builtin_clz" as "RetracePos - RETRACE_SHORT" will never equal 0 652 | SavedCur -= 4 + ((0x20 - (clz (RetracePos - RETRACE_SHORT))) - 0x01); // Highest MSB set + 4 653 | } 654 | 655 | // --- Copy Check --- 656 | 657 | SavedCur -= SavedCopies [CopyCur]; 658 | 659 | // --- Saved Bits Check --- 660 | 661 | if (SavedCur > SavedBest) 662 | { 663 | SavedBest = SavedCur; 664 | CopyBest = CopyCur; 665 | RetraceBest = RetracePos; 666 | if (CopyBest == CopyTotal) 667 | { 668 | break; 669 | } 670 | } 671 | } 672 | RetraceLoc = Retraces [(RetraceLoc & WINDOW_WRAP)]; 673 | } 674 | SavedTotal += SavedBest; 675 | 676 | // --- Documenting Results --- 677 | 678 | if (SavedBest == -0x01) 679 | { 680 | *Document++ = -0x01; 681 | *Document++ = Word; 682 | } 683 | else 684 | { 685 | if (RetraceBest > 0xFFFF) 686 | { 687 | *Document++ = ((RetraceBest - 0xFFFF) << 0x0B) | CopyBest; 688 | *Document++ = 0xFFFF; 689 | } 690 | else 691 | { 692 | *Document++ = CopyBest; 693 | *Document++ = RetraceBest; 694 | } 695 | HuffRetrace [RetraceBest]++; 696 | HuffCopy [CopyBest]++; 697 | } 698 | DocuSize++; 699 | 700 | // --- Update Retraces --- 701 | 702 | do 703 | { 704 | WindowPos = WindowLoc; 705 | Word = Window [(WindowLoc++ & WINDOW_WRAP)] & 0xFF; 706 | Word |= Window [(WindowLoc & WINDOW_WRAP)] << 0x08; 707 | Retraces [(WindowPos & WINDOW_WRAP)] = RetStart [Word]; 708 | RetStart [Word] = WindowPos; 709 | RetCount [Word]++; 710 | WindowWord [(WindowPos & WINDOW_WRAP)] = Word; 711 | WindowCount--; 712 | } 713 | while (--CopyBest > 0x00); 714 | } 715 | free (Input); 716 | free (RetStart); 717 | free (RetCount); 718 | free (Retraces); 719 | free (WindowWord); 720 | free (Window); 721 | 722 | // ----------------------------------------------------------------------------- 723 | // Calculating Huffman Retrace Tree 724 | // ----------------------------------------------------------------------------- 725 | 726 | TwizAlloc (int*, HuffRetChain, ((RETRACE_MAX + 0x01) + 0x01) * sizeof (int)); 727 | int HuffRetOrder [HUFFRET_BITSIZE] = { 0x00 }; 728 | 729 | // --- Creating a chain to speed up searches --- 730 | 731 | for (HuffRetSize = 0x00, Count = 0x00; Count < (RETRACE_MAX + 0x01); Count++) 732 | { 733 | if (HuffRetrace [Count] > 0x01) 734 | { 735 | HuffRetChain [HuffRetSize++] = Count; 736 | } 737 | } 738 | 739 | // --- Main Search & Reorder --- 740 | 741 | HuffRetBest = 0x01; 742 | BinaryRange = 1 + 1; 743 | while (BinaryRange < HUFFRET_BITSIZE + (1 + 1) && HuffRetBest != 0x00) 744 | { 745 | HuffReadOnly = HuffRetChain - 0x01; 746 | HuffRetBest = 0x00; 747 | for (Count = HuffRetSize; Count > 0x00; Count--) 748 | { 749 | RetraceBest = *++HuffReadOnly; 750 | if (HuffRetrace [RetraceBest] > HuffRetBest) 751 | { 752 | HuffRetBest = HuffRetrace [RetraceBest]; 753 | HuffRetOff = HuffReadOnly; 754 | } 755 | } 756 | if (HuffRetBest != 0x00) 757 | { 758 | RetraceBest = *HuffRetOff; 759 | if (RetraceBest <= RETRACE_SHORT) 760 | { 761 | SavedCur = 3 + 1; 762 | } 763 | else 764 | { 765 | // It's OK to use "__builtin_clz" as "RetraceBest - RETRACE_SHORT" will never equal 0 766 | SavedCur = 4 + ((0x20 - (clz (RetraceBest - RETRACE_SHORT))) - 0x01); // Highest MSB set + 4 767 | } 768 | if (SavedCur > BinaryRange) 769 | { 770 | HuffRetOrder [(BinaryRange++ - (1 + 1))] = RetraceBest; 771 | } 772 | HuffRetrace [RetraceBest] = 0x00; 773 | } 774 | } 775 | HuffRetSize = BinaryRange - (1 + 1); 776 | 777 | // ----------------------------------------------------------------------------- 778 | // Calculating Huffman Copy Tree 779 | // ----------------------------------------------------------------------------- 780 | 781 | TwizAlloc (int*, HuffCopyChain, ((COPY_MAX + 0x01) + 0x01) * sizeof (int)); 782 | int HuffCopyOrder [HUFFCOPY_BITSIZE] = { 0x00 }; 783 | 784 | // --- Creating a chain to speed up searches --- 785 | 786 | for (HuffCopySize = 0x00, Count = 0x00; Count < (COPY_MAX + 0x01); Count++) 787 | { 788 | if (HuffCopy [Count] > 0x01) 789 | { 790 | HuffCopyChain [HuffCopySize++] = Count; 791 | } 792 | } 793 | 794 | // --- Main Search & Reorder --- 795 | 796 | HuffCopyBest = 0x01; 797 | BinaryRange = 1 + 1 + 2; 798 | while (BinaryRange < HUFFCOPY_BITSIZE + (1 + 1 + 2) && HuffCopyBest != 0x00) 799 | { 800 | HuffReadOnly = HuffCopyChain - 0x01; 801 | HuffCopyBest = 0x00; 802 | for (Count = HuffCopySize; Count > 0x00; Count--) 803 | { 804 | CopyBest = *++HuffReadOnly; 805 | if (HuffCopy [CopyBest] > HuffCopyBest) 806 | { 807 | HuffCopyBest = HuffCopy [CopyBest]; 808 | HuffCopyOff = HuffReadOnly; 809 | } 810 | } 811 | if (HuffCopyBest != 0x00) 812 | { 813 | CopyBest = *HuffCopyOff; 814 | SavedCur = SavedCopies [CopyBest]; 815 | if (SavedCur > BinaryRange) 816 | { 817 | HuffCopyOrder [(BinaryRange++ - (1 + 1 + 2))] = CopyBest; 818 | } 819 | HuffCopy [CopyBest] = 0x00; 820 | } 821 | } 822 | HuffCopySize = BinaryRange - (1 + 1 + 2); 823 | 824 | // ----------------------------------------------------------------------------- 825 | // Setting up data dumping 826 | // ----------------------------------------------------------------------------- 827 | 828 | // --- Creating Memory & Prep --- 829 | 830 | TwizAlloc (char*, Output, ((((InputSize * 0x08) - SavedTotal) / 0x08) + 0x01) + 0x1000); // Adding an extra 1000 for counters that are written first... 831 | OutputAccess = Output; 832 | 833 | // --- Bit Field Preparation --- 834 | 835 | BitField = 0x00; 836 | BitCount = 0x09; 837 | BitLoc = OutputAccess++; 838 | OutputSize = 0x01; 839 | 840 | // --- Saving Decompression Size --- 841 | 842 | Offset = InputSize; 843 | if (Offset == 0x00) 844 | { 845 | Count = 0x00; 846 | } 847 | else 848 | { 849 | Count = ((0x20 - (clz (Offset))) - 0x01); // Highest MSB set 850 | } 851 | Offset <<= 0x20 - Count; 852 | PLACEBIT (Count >> 4, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 853 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 854 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 855 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 856 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 857 | while (--Count >= 0x00) 858 | { 859 | PLACEBIT (Offset >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 860 | Offset <<= 0x01; 861 | } 862 | 863 | // --- Saving Section Count --- 864 | 865 | Offset = DocuSize; 866 | if (Offset == 0x00) 867 | { 868 | Count = 0x00; 869 | } 870 | else 871 | { 872 | Count = ((0x20 - (clz (Offset))) - 0x01); // Highest MSB set 873 | } 874 | Offset <<= 0x20 - Count; 875 | PLACEBIT (Count >> 4, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 876 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 877 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 878 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 879 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 880 | while (--Count >= 0x00) 881 | { 882 | PLACEBIT (Offset >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 883 | Offset <<= 0x01; 884 | } 885 | 886 | // --- Saving/Creating Huffman Retrace Tree --- 887 | 888 | memset (HuffRetrace, 0x00, (RETRACE_MAX + 0x01) * sizeof (int)); 889 | Offset = HuffRetSize; 890 | 891 | if (Offset == 0x00) 892 | { 893 | Count = 0x00; 894 | } 895 | else 896 | { 897 | Count = (0x20 - (clz (Offset))); // Highest MSB set (Meant to have the "- 0x01" removed, incase huffman tree is empty... 898 | } 899 | Offset <<= 0x20 - Count; 900 | PLACEBIT (Count >> 4, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 901 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 902 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 903 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 904 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 905 | while (--Count >= 0x00) 906 | { 907 | PLACEBIT (Offset >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 908 | Offset <<= 0x01; 909 | } 910 | for (HuffRetLoc = 0x00; HuffRetLoc < HuffRetSize; HuffRetLoc++) 911 | { 912 | Offset = HuffRetOrder [HuffRetLoc]; 913 | HuffRetrace [Offset] = HuffRetLoc + 0x01; 914 | if (Offset == 0x00) 915 | { 916 | Count = 0x00; 917 | } 918 | else 919 | { 920 | Count = ((0x20 - (clz (Offset))) - 0x01); // Highest MSB set 921 | } 922 | Offset <<= 0x20 - Count; 923 | PLACEBIT (Count >> 4, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 924 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 925 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 926 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 927 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 928 | while (--Count >= 0x00) 929 | { 930 | PLACEBIT (Offset >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 931 | Offset <<= 0x01; 932 | } 933 | } 934 | 935 | // --- Saving/Creating Huffman Copy Tree --- 936 | 937 | memset (HuffCopy, 0x00, (COPY_MAX + 0x01) * sizeof (int)); 938 | Offset = HuffCopySize; 939 | 940 | if (Offset == 0x00) 941 | { 942 | Count = 0x00; 943 | } 944 | else 945 | { 946 | Count = (0x20 - (clz (Offset))); // Highest MSB set (Meant to have the "- 0x01" removed, incase huffman tree is empty... 947 | } 948 | Offset <<= 0x20 - Count; 949 | PLACEBIT (Count >> 4, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 950 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 951 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 952 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 953 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 954 | while (--Count >= 0x00) 955 | { 956 | PLACEBIT (Offset >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 957 | Offset <<= 0x01; 958 | } 959 | for (HuffCopyLoc = 0x00; HuffCopyLoc < HuffCopySize; HuffCopyLoc++) 960 | { 961 | Offset = HuffCopyOrder [HuffCopyLoc]; 962 | HuffCopy [Offset] = HuffCopyLoc + 0x01; 963 | if (Offset == 0x00) 964 | { 965 | Count = 0x00; 966 | } 967 | else 968 | { 969 | Count = ((0x20 - (clz (Offset))) - 0x01); // Highest MSB set 970 | } 971 | Offset <<= 0x20 - Count; 972 | PLACEBIT (Count >> 4, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 973 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 974 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 975 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 976 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 977 | while (--Count >= 0x00) 978 | { 979 | PLACEBIT (Offset >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 980 | Offset <<= 0x01; 981 | } 982 | } 983 | 984 | // ----------------------------------------------------------------------------- 985 | // Main Compression Loop 986 | // ----------------------------------------------------------------------------- 987 | 988 | Document = DocuStore; 989 | while (--DocuSize >= 0x00) 990 | { 991 | if (*Document == (-0x01 & 0xFFFF)) 992 | { 993 | // --- Uncompressed --- 994 | 995 | Document++; 996 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 997 | *OutputAccess++ = *Document++; 998 | OutputSize++; 999 | } 1000 | else 1001 | { 1002 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1003 | CopyBest = (*Document & 0x7FF); 1004 | RetraceBest = (*Document++ >> 0x0B) & 0x1F; 1005 | RetraceBest += (*Document++) & 0xFFFF; 1006 | if (HuffRetrace [RetraceBest] != 0x00) 1007 | { 1008 | // --- Huffman Retrace --- 1009 | 1010 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1011 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1012 | Count = HuffRetrace [RetraceBest] - 0x01; 1013 | while (Count-- > 0x00) 1014 | { 1015 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1016 | } 1017 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1018 | } 1019 | else if (RetraceBest <= RETRACE_SHORT) 1020 | { 1021 | // --- Short Retrace --- 1022 | 1023 | RetraceBest--; 1024 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); // 1 1025 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); // 0 1026 | PLACEBIT (RetraceBest >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // R 1027 | PLACEBIT (RetraceBest >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // R 1028 | PLACEBIT (RetraceBest >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // R 1029 | } 1030 | else 1031 | { 1032 | // --- Distant Retrace --- 1033 | 1034 | RetraceBest -= RETRACE_SHORT; 1035 | Count = (0x20 - (clz (RetraceBest))) - 0x01; 1036 | RetraceBest <<= (0x20 - Count); 1037 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); // 0 1038 | PLACEBIT (Count >> 3, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // S 1039 | PLACEBIT (Count >> 2, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // S 1040 | PLACEBIT (Count >> 1, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // S 1041 | PLACEBIT (Count >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // S 1042 | while (--Count >= 0) // R... 1043 | { 1044 | PLACEBIT (RetraceBest >> 0x1F, BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1045 | RetraceBest <<= 0x01; 1046 | } 1047 | } 1048 | 1049 | if (HuffCopy [CopyBest] != 0x00) 1050 | { 1051 | // --- Huffman Copy --- 1052 | 1053 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1054 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1055 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1056 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1057 | Count = HuffCopy [CopyBest] - 0x01; 1058 | while (Count-- > 0x00) 1059 | { 1060 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1061 | } 1062 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1063 | } 1064 | else if (CopyBest < (COPY_MIN + 0x02)) 1065 | { 1066 | // --- Short Copy --- 1067 | 1068 | CopyBest -= CopySubtract [CopyBest]; 1069 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); // 0 1070 | PLACEBIT (CopyBest >> 0, BitField, BitCount, BitLoc, OutputAccess, OutputSize); // C 1071 | } 1072 | else 1073 | { 1074 | // --- Distant Copy --- 1075 | 1076 | Count = CopyBitFill [CopyBest]; 1077 | if (Count < 0x00) 1078 | { 1079 | Count = -Count; 1080 | ExtendSet = -0x01; 1081 | } 1082 | do // 1... 1083 | { 1084 | SETBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1085 | } 1086 | while (--Count > 0x00); 1087 | if (ExtendSet != 0x00) 1088 | { 1089 | ExtendSet = 0x00; 1090 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); // 0 - For extended copy 1091 | } 1092 | Count = CopyBitCount [CopyBest]; 1093 | CopyBest -= CopySubtract [CopyBest]; 1094 | do // C... 1095 | { 1096 | PLACEBIT ((CopyBest >> --Count), BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1097 | } 1098 | while (Count > 0x00); 1099 | } 1100 | } 1101 | } 1102 | free (DocuStore); 1103 | do 1104 | { 1105 | CLEARBIT (BitField, BitCount, BitLoc, OutputAccess, OutputSize); 1106 | } 1107 | while (BitCount != 0x08); 1108 | OutputSize--; 1109 | 1110 | // ----------------------------------------------------------------------------- 1111 | // Finish/Cleanup 1112 | // ----------------------------------------------------------------------------- 1113 | 1114 | Input = Output; 1115 | InputSize = OutputSize; 1116 | 1117 | free (HuffRetrace); 1118 | free (HuffRetChain); 1119 | free (HuffCopy); 1120 | free (HuffCopyChain); 1121 | } 1122 | 1123 | // ============================================================================= 1124 | // ----------------------------------------------------------------------------- 1125 | // Twizzler Decompression Algorithm 1126 | // ----------------------------------------------------------------------------- 1127 | 1128 | void TwizDec (char *&Input, int &InputSize) 1129 | 1130 | { 1131 | const char *InputAccess = Input; 1132 | const char *InputRetrace; 1133 | char *Output; 1134 | char *OutputAccess; 1135 | int OutputLoc = 0x00; 1136 | int OutputSize; 1137 | int SectionCount; 1138 | int RetraceBest; 1139 | int CopyBest; 1140 | int HuffRetLoc; 1141 | int HuffRetSize; 1142 | int HuffCopyLoc; 1143 | int HuffCopySize; 1144 | int AddBit; 1145 | int CheckBit; 1146 | int CountBit; 1147 | int AdvanceBit; 1148 | int CountCur; 1149 | int LimitBit; 1150 | int Count, Offset; 1151 | char BitCount = 0x09; 1152 | char BitField = *InputAccess++; 1153 | int HuffRetOrder [HUFFRET_BITSIZE]; 1154 | int HuffCopyOrder [HUFFCOPY_BITSIZE]; 1155 | 1156 | // --- Getting Decompression Size --- 1157 | 1158 | Count = 0x00; 1159 | GETBIT (Count, BitField, BitCount, InputAccess); 1160 | GETBIT (Count, BitField, BitCount, InputAccess); 1161 | GETBIT (Count, BitField, BitCount, InputAccess); 1162 | GETBIT (Count, BitField, BitCount, InputAccess); 1163 | GETBIT (Count, BitField, BitCount, InputAccess); 1164 | OutputSize = 0x01; 1165 | while (Count-- > 0x00) 1166 | { 1167 | GETBIT (OutputSize, BitField, BitCount, InputAccess); 1168 | } 1169 | // --- Getting Section Counter --- 1170 | 1171 | Count = 0x00; 1172 | GETBIT (Count, BitField, BitCount, InputAccess); 1173 | GETBIT (Count, BitField, BitCount, InputAccess); 1174 | GETBIT (Count, BitField, BitCount, InputAccess); 1175 | GETBIT (Count, BitField, BitCount, InputAccess); 1176 | GETBIT (Count, BitField, BitCount, InputAccess); 1177 | SectionCount = 0x01; 1178 | while (Count-- > 0x00) 1179 | { 1180 | GETBIT (SectionCount, BitField, BitCount, InputAccess); 1181 | } 1182 | 1183 | // --- Unpacking Huffman Retrace Tree --- 1184 | 1185 | Count = 0x00; 1186 | GETBIT (Count, BitField, BitCount, InputAccess); 1187 | GETBIT (Count, BitField, BitCount, InputAccess); 1188 | GETBIT (Count, BitField, BitCount, InputAccess); 1189 | GETBIT (Count, BitField, BitCount, InputAccess); 1190 | GETBIT (Count, BitField, BitCount, InputAccess); 1191 | HuffRetSize = 0x00; // Meant to be 0, incase huffman tree is empty... 1192 | while (Count-- > 0x00) 1193 | { 1194 | GETBIT (HuffRetSize, BitField, BitCount, InputAccess); 1195 | } 1196 | 1197 | for (HuffRetLoc = 0x00; HuffRetLoc < HuffRetSize; HuffRetLoc++) 1198 | { 1199 | Count = 0x00; 1200 | GETBIT (Count, BitField, BitCount, InputAccess); 1201 | GETBIT (Count, BitField, BitCount, InputAccess); 1202 | GETBIT (Count, BitField, BitCount, InputAccess); 1203 | GETBIT (Count, BitField, BitCount, InputAccess); 1204 | GETBIT (Count, BitField, BitCount, InputAccess); 1205 | Offset = 0x01; 1206 | while (Count-- > 0x00) 1207 | { 1208 | GETBIT (Offset, BitField, BitCount, InputAccess); 1209 | } 1210 | HuffRetOrder [HuffRetLoc] = Offset; 1211 | } 1212 | 1213 | // --- Unpacking Huffman Copy Tree --- 1214 | 1215 | Count = 0x00; 1216 | GETBIT (Count, BitField, BitCount, InputAccess); 1217 | GETBIT (Count, BitField, BitCount, InputAccess); 1218 | GETBIT (Count, BitField, BitCount, InputAccess); 1219 | GETBIT (Count, BitField, BitCount, InputAccess); 1220 | GETBIT (Count, BitField, BitCount, InputAccess); 1221 | HuffCopySize = 0x00; // Meant to be 0, incase huffman tree is empty... 1222 | while (Count-- > 0x00) 1223 | { 1224 | GETBIT (HuffCopySize, BitField, BitCount, InputAccess); 1225 | } 1226 | 1227 | for (HuffCopyLoc = 0x00; HuffCopyLoc < HuffCopySize; HuffCopyLoc++) 1228 | { 1229 | Count = 0x00; 1230 | GETBIT (Count, BitField, BitCount, InputAccess); 1231 | GETBIT (Count, BitField, BitCount, InputAccess); 1232 | GETBIT (Count, BitField, BitCount, InputAccess); 1233 | GETBIT (Count, BitField, BitCount, InputAccess); 1234 | GETBIT (Count, BitField, BitCount, InputAccess); 1235 | Offset = 0x01; 1236 | while (Count-- > 0x00) 1237 | { 1238 | GETBIT (Offset, BitField, BitCount, InputAccess); 1239 | } 1240 | HuffCopyOrder [HuffCopyLoc] = Offset; 1241 | } 1242 | 1243 | // --- Creating Memory & Prep --- 1244 | 1245 | do 1246 | { 1247 | Output = (char*) malloc (OutputSize); 1248 | } 1249 | while (Output == NULL); 1250 | OutputAccess = Output; 1251 | 1252 | // ----------------------------------------------------------------------------- 1253 | // Main Decompression Loop 1254 | // ----------------------------------------------------------------------------- 1255 | 1256 | while (--SectionCount >= 0x00) 1257 | { 1258 | Count = 0x00; 1259 | GETBIT (Count, BitField, BitCount, InputAccess); 1260 | if (Count == 0x00) 1261 | { 1262 | // --- Uncompressed --- 1263 | 1264 | *OutputAccess++ = *InputAccess++; 1265 | OutputLoc++; 1266 | } 1267 | else 1268 | { 1269 | RetraceBest = 0x00; 1270 | Count = 0x00; 1271 | GETBIT (Count, BitField, BitCount, InputAccess); 1272 | if (Count != 0x00) 1273 | { 1274 | Count = 0x00; 1275 | GETBIT (Count, BitField, BitCount, InputAccess); 1276 | if (Count != 0x00) 1277 | { 1278 | // --- Huffman Retrace --- 1279 | 1280 | Offset = 0x00; 1281 | HuffRetLoc = -0x01; 1282 | do 1283 | { 1284 | HuffRetLoc++; 1285 | GETBIT (Offset, BitField, BitCount, InputAccess); 1286 | } 1287 | while ((Offset & 0x01) != 0x00); 1288 | RetraceBest = HuffRetOrder [HuffRetLoc]; 1289 | } 1290 | else 1291 | { 1292 | // --- Short Retrace --- 1293 | 1294 | GETBIT (RetraceBest, BitField, BitCount, InputAccess); 1295 | GETBIT (RetraceBest, BitField, BitCount, InputAccess); 1296 | GETBIT (RetraceBest, BitField, BitCount, InputAccess); 1297 | RetraceBest++; 1298 | } 1299 | } 1300 | else 1301 | { 1302 | // --- Distant Retrace --- 1303 | 1304 | Count = 0x00; 1305 | GETBIT (Count, BitField, BitCount, InputAccess); 1306 | GETBIT (Count, BitField, BitCount, InputAccess); 1307 | GETBIT (Count, BitField, BitCount, InputAccess); 1308 | GETBIT (Count, BitField, BitCount, InputAccess); 1309 | RetraceBest = 0x01; 1310 | while (Count-- > 0x00) 1311 | { 1312 | GETBIT (RetraceBest, BitField, BitCount, InputAccess); 1313 | } 1314 | RetraceBest += RETRACE_SHORT; 1315 | 1316 | } 1317 | CopyBest = 0x00; 1318 | Count = 0x00; 1319 | GETBIT (Count, BitField, BitCount, InputAccess); 1320 | if (Count == 0x00) 1321 | { 1322 | // --- Short Copy --- 1323 | 1324 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1325 | } 1326 | else 1327 | { 1328 | // --- Distant Copy --- 1329 | 1330 | CheckBit = 0x03; 1331 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1332 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1333 | if (CopyBest == CheckBit) 1334 | { 1335 | CountBit = 0x03; 1336 | LimitBit = 0x02; 1337 | AddBit = 0x00; 1338 | AdvanceBit = 0x01; 1339 | do 1340 | { 1341 | if (AdvanceBit == 0x01) 1342 | { 1343 | Count = 0x00; 1344 | GETBIT (Count, BitField, BitCount, InputAccess); 1345 | if (Count == 0x00) 1346 | { 1347 | // --- Huffman Copy --- 1348 | 1349 | Offset = 0x00; 1350 | HuffCopyLoc = -0x01; 1351 | do 1352 | { 1353 | HuffCopyLoc++; 1354 | GETBIT (Offset, BitField, BitCount, InputAccess); 1355 | } 1356 | while ((Offset & 0x01) != 0x00); 1357 | CopyBest = HuffCopyOrder [HuffCopyLoc] - (COPY_MIN + COPY_MIN); 1358 | break; 1359 | } 1360 | AdvanceBit--; 1361 | } 1362 | else if (AdvanceBit == 0x00) 1363 | { 1364 | Count = 0x00; 1365 | GETBIT (Count, BitField, BitCount, InputAccess); 1366 | if (Count == 0x00) 1367 | { 1368 | // --- Extended Copy --- 1369 | 1370 | CopyBest = 0x00; 1371 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1372 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1373 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1374 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1375 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1376 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1377 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1378 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1379 | GETBIT (CopyBest, BitField, BitCount, InputAccess); 1380 | CopyBest += COPY_EXT - (COPY_MIN + COPY_MIN); 1381 | break; 1382 | } 1383 | AdvanceBit--; 1384 | } 1385 | Count = 0x00; 1386 | for (CountCur = CountBit; CountCur > 0x00; CountCur--) 1387 | { 1388 | GETBIT (Count, BitField, BitCount, InputAccess); 1389 | } 1390 | CountBit++; 1391 | AddBit += CheckBit; 1392 | CopyBest = (Count + AddBit); 1393 | CheckBit = (CheckBit << 0x01) | 0x01; 1394 | } 1395 | while (Count == CheckBit && LimitBit-- > 0x00); 1396 | } 1397 | CopyBest += COPY_MIN; 1398 | } 1399 | CopyBest += COPY_MIN; 1400 | 1401 | // --- Unpacking LZ --- 1402 | 1403 | InputRetrace = Output + (OutputLoc - RetraceBest); 1404 | OutputLoc += CopyBest; 1405 | while (--CopyBest >= 0x00) 1406 | { 1407 | *OutputAccess++ = *InputRetrace++; 1408 | } 1409 | } 1410 | } 1411 | free (Input); 1412 | Input = Output; 1413 | InputSize = OutputLoc; 1414 | } 1415 | 1416 | // ============================================================================= 1417 | 1418 | } 1419 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/Twizzler/Twizzler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" void TwizComp(char *&Input, int &InputSize, bool moduled = false, int module_size = 0); 4 | extern "C" void TwizDec(char *&Input, int &InputSize); 5 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | #include "ClassFactory.h" 4 | #include 5 | 6 | // {76F76F87-9DA0-48D6-9277-238FCEC133CA} 7 | static const CLSID CLSID_FW_KENSC = 8 | { 0x76f76f87, 0x9da0, 0x48d6, { 0x92, 0x77, 0x23, 0x8f, 0xce, 0xc1, 0x33, 0xca } }; 9 | 10 | 11 | long g_cDllRef = 0; 12 | 13 | BOOL APIENTRY DllMain( HMODULE hModule, 14 | DWORD ul_reason_for_call, 15 | LPVOID lpReserved 16 | ) 17 | { 18 | switch (ul_reason_for_call) 19 | { 20 | case DLL_PROCESS_ATTACH: 21 | { 22 | DisableThreadLibraryCalls(hModule); 23 | } 24 | break; 25 | case DLL_THREAD_ATTACH: 26 | case DLL_THREAD_DETACH: 27 | case DLL_PROCESS_DETACH: 28 | break; 29 | } 30 | return TRUE; 31 | } 32 | 33 | STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) 34 | { 35 | HRESULT hr = CLASS_E_CLASSNOTAVAILABLE; 36 | 37 | if (IsEqualCLSID(CLSID_FW_KENSC, rclsid)) 38 | { 39 | hr = E_OUTOFMEMORY; 40 | 41 | CClassFactory *pClassFactory = new CClassFactory(); 42 | if (pClassFactory) 43 | { 44 | hr = pClassFactory->QueryInterface(riid, ppv); 45 | pClassFactory->Release(); 46 | } 47 | } 48 | 49 | return hr; 50 | } 51 | 52 | STDAPI DllCanUnloadNow() 53 | { 54 | return g_cDllRef > 0 ? S_FALSE : S_OK; 55 | } -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // FW-KENSC-ShellExt.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | #define NOMINMAX 12 | // Windows Header Files: 13 | #include 14 | 15 | 16 | 17 | // TODO: reference additional headers your program requires here 18 | -------------------------------------------------------------------------------- /FW-KENSC-ShellExt/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FW-KENSC-ShellExt 2 | Windows Shell Extension for FW-KENSC 3 | 4 | Uses code from https://github.com/flamewing/mdcomp 5 | 6 | Also uses the Twizzler compression: http://sonicresearch.org/community/index.php?threads/twizzler-compression.4708/ 7 | --------------------------------------------------------------------------------