commit
42ce77ce05
229 changed files with 146810 additions and 0 deletions
@ -0,0 +1,358 @@
|
||||
# ELF object file. |
||||
*.o |
||||
|
||||
# PE shared library and associated files. |
||||
*.lib |
||||
*.exp |
||||
*.dll |
||||
|
||||
# PE executable. |
||||
*.exe |
||||
|
||||
# GCC dependency file. |
||||
*.d |
||||
|
||||
# Resource file. |
||||
*.res |
||||
|
||||
# Created by https://www.gitignore.io/api/visualstudio |
||||
|
||||
### VisualStudio ### |
||||
## Ignore Visual Studio temporary files, build results, and |
||||
## files generated by popular Visual Studio add-ons. |
||||
## |
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore |
||||
|
||||
# User-specific files |
||||
*.suo |
||||
*.user |
||||
*.userosscache |
||||
*.sln.docstates |
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio) |
||||
*.userprefs |
||||
|
||||
# Build results |
||||
[Dd]ebug/ |
||||
[Dd]ebugPublic/ |
||||
[Rr]elease/ |
||||
[Rr]eleases/ |
||||
x64/ |
||||
x86/ |
||||
bld/ |
||||
[Bb]in/ |
||||
[Oo]bj/ |
||||
[Ll]og/ |
||||
WinDebug/ |
||||
WinRel/ |
||||
|
||||
# Visual Studio 2015/2017 cache/options directory |
||||
.vs/ |
||||
# Uncomment if you have tasks that create the project's static files in wwwroot |
||||
#wwwroot/ |
||||
|
||||
# Visual Studio 2017 auto generated files |
||||
Generated\ Files/ |
||||
|
||||
# MSTest test Results |
||||
[Tt]est[Rr]esult*/ |
||||
[Bb]uild[Ll]og.* |
||||
|
||||
# NUNIT |
||||
*.VisualState.xml |
||||
TestResult.xml |
||||
|
||||
# Build Results of an ATL Project |
||||
[Dd]ebugPS/ |
||||
[Rr]eleasePS/ |
||||
dlldata.c |
||||
|
||||
# Benchmark Results |
||||
BenchmarkDotNet.Artifacts/ |
||||
|
||||
# .NET Core |
||||
project.lock.json |
||||
project.fragment.lock.json |
||||
artifacts/ |
||||
|
||||
# StyleCop |
||||
StyleCopReport.xml |
||||
|
||||
# Files built by Visual Studio |
||||
*_i.c |
||||
*_p.c |
||||
*_i.h |
||||
*.ilk |
||||
*.meta |
||||
*.obj |
||||
*.iobj |
||||
*.pch |
||||
*.pdb |
||||
*.ipdb |
||||
*.pgc |
||||
*.pgd |
||||
*.rsp |
||||
*.sbr |
||||
*.tlb |
||||
*.tli |
||||
*.tlh |
||||
*.tmp |
||||
*.tmp_proj |
||||
*.log |
||||
*.vspscc |
||||
*.vssscc |
||||
.builds |
||||
*.pidb |
||||
*.svclog |
||||
*.scc |
||||
|
||||
# Chutzpah Test files |
||||
_Chutzpah* |
||||
|
||||
# Visual C++ cache files |
||||
ipch/ |
||||
*.aps |
||||
*.ncb |
||||
*.opendb |
||||
*.opensdf |
||||
*.sdf |
||||
*.cachefile |
||||
*.VC.db |
||||
*.VC.VC.opendb |
||||
|
||||
# Visual Studio profiler |
||||
*.psess |
||||
*.vsp |
||||
*.vspx |
||||
*.sap |
||||
|
||||
# Visual Studio Trace Files |
||||
*.e2e |
||||
|
||||
# TFS 2012 Local Workspace |
||||
$tf/ |
||||
|
||||
# Guidance Automation Toolkit |
||||
*.gpState |
||||
|
||||
# ReSharper is a .NET coding add-in |
||||
_ReSharper*/ |
||||
*.[Rr]e[Ss]harper |
||||
*.DotSettings.user |
||||
|
||||
# JustCode is a .NET coding add-in |
||||
.JustCode |
||||
|
||||
# TeamCity is a build add-in |
||||
_TeamCity* |
||||
|
||||
# DotCover is a Code Coverage Tool |
||||
*.dotCover |
||||
|
||||
# AxoCover is a Code Coverage Tool |
||||
.axoCover/* |
||||
!.axoCover/settings.json |
||||
|
||||
# Visual Studio code coverage results |
||||
*.coverage |
||||
*.coveragexml |
||||
|
||||
# NCrunch |
||||
_NCrunch_* |
||||
.*crunch*.local.xml |
||||
nCrunchTemp_* |
||||
|
||||
# MightyMoose |
||||
*.mm.* |
||||
AutoTest.Net/ |
||||
|
||||
# Web workbench (sass) |
||||
.sass-cache/ |
||||
|
||||
# Installshield output folder |
||||
[Ee]xpress/ |
||||
|
||||
# DocProject is a documentation generator add-in |
||||
DocProject/buildhelp/ |
||||
DocProject/Help/*.HxT |
||||
DocProject/Help/*.HxC |
||||
DocProject/Help/*.hhc |
||||
DocProject/Help/*.hhk |
||||
DocProject/Help/*.hhp |
||||
DocProject/Help/Html2 |
||||
DocProject/Help/html |
||||
|
||||
# Click-Once directory |
||||
publish/ |
||||
|
||||
# Publish Web Output |
||||
*.[Pp]ublish.xml |
||||
*.azurePubxml |
||||
# Note: Comment the next line if you want to checkin your web deploy settings, |
||||
# but database connection strings (with potential passwords) will be unencrypted |
||||
*.pubxml |
||||
*.publishproj |
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to |
||||
# checkin your Azure Web App publish settings, but sensitive information contained |
||||
# in these scripts will be unencrypted |
||||
PublishScripts/ |
||||
|
||||
# NuGet Packages |
||||
*.nupkg |
||||
# The packages folder can be ignored because of Package Restore |
||||
**/[Pp]ackages/* |
||||
# except build/, which is used as an MSBuild target. |
||||
!**/[Pp]ackages/build/ |
||||
# Uncomment if necessary however generally it will be regenerated when needed |
||||
#!**/[Pp]ackages/repositories.config |
||||
# NuGet v3's project.json files produces more ignorable files |
||||
*.nuget.props |
||||
*.nuget.targets |
||||
|
||||
# Microsoft Azure Build Output |
||||
csx/ |
||||
*.build.csdef |
||||
|
||||
# Microsoft Azure Emulator |
||||
ecf/ |
||||
rcf/ |
||||
|
||||
# Windows Store app package directories and files |
||||
AppPackages/ |
||||
BundleArtifacts/ |
||||
Package.StoreAssociation.xml |
||||
_pkginfo.txt |
||||
*.appx |
||||
|
||||
# Visual Studio cache files |
||||
# files ending in .cache can be ignored |
||||
*.[Cc]ache |
||||
# but keep track of directories ending in .cache |
||||
!*.[Cc]ache/ |
||||
|
||||
# Others |
||||
ClientBin/ |
||||
~$* |
||||
*~ |
||||
*.dbmdl |
||||
*.dbproj.schemaview |
||||
*.jfm |
||||
*.pfx |
||||
*.publishsettings |
||||
orleans.codegen.cs |
||||
|
||||
# Including strong name files can present a security risk |
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424) |
||||
#*.snk |
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components |
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) |
||||
#bower_components/ |
||||
|
||||
# RIA/Silverlight projects |
||||
Generated_Code/ |
||||
|
||||
# Backup & report files from converting an old project file |
||||
# to a newer Visual Studio version. Backup files are not needed, |
||||
# because we have git ;-) |
||||
_UpgradeReport_Files/ |
||||
Backup*/ |
||||
UpgradeLog*.XML |
||||
UpgradeLog*.htm |
||||
ServiceFabricBackup/ |
||||
*.rptproj.bak |
||||
|
||||
# SQL Server files |
||||
*.mdf |
||||
*.ldf |
||||
*.ndf |
||||
|
||||
# Business Intelligence projects |
||||
*.rdl.data |
||||
*.bim.layout |
||||
*.bim_*.settings |
||||
*.rptproj.rsuser |
||||
|
||||
# Microsoft Fakes |
||||
FakesAssemblies/ |
||||
|
||||
# GhostDoc plugin setting file |
||||
*.GhostDoc.xml |
||||
|
||||
# Node.js Tools for Visual Studio |
||||
.ntvs_analysis.dat |
||||
node_modules/ |
||||
|
||||
# Visual Studio 6 build log |
||||
*.plg |
||||
|
||||
# Visual Studio 6 workspace options file |
||||
*.opt |
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) |
||||
*.vbw |
||||
|
||||
# Visual Studio LightSwitch build output |
||||
**/*.HTMLClient/GeneratedArtifacts |
||||
**/*.DesktopClient/GeneratedArtifacts |
||||
**/*.DesktopClient/ModelManifest.xml |
||||
**/*.Server/GeneratedArtifacts |
||||
**/*.Server/ModelManifest.xml |
||||
_Pvt_Extensions |
||||
|
||||
# Paket dependency manager |
||||
.paket/paket.exe |
||||
paket-files/ |
||||
|
||||
# FAKE - F# Make |
||||
.fake/ |
||||
|
||||
# JetBrains Rider |
||||
.idea/ |
||||
*.sln.iml |
||||
|
||||
# CodeRush |
||||
.cr/ |
||||
|
||||
# Python Tools for Visual Studio (PTVS) |
||||
__pycache__/ |
||||
*.pyc |
||||
|
||||
# Cake - Uncomment if you are using it |
||||
# tools/** |
||||
# !tools/packages.config |
||||
|
||||
# Tabs Studio |
||||
*.tss |
||||
|
||||
# Telerik's JustMock configuration file |
||||
*.jmconfig |
||||
|
||||
# BizTalk build output |
||||
*.btp.cs |
||||
*.btm.cs |
||||
*.odx.cs |
||||
*.xsd.cs |
||||
|
||||
# OpenCover UI analysis results |
||||
OpenCover/ |
||||
|
||||
# Azure Stream Analytics local run output |
||||
ASALocalRun/ |
||||
|
||||
# MSBuild Binary and Structured Log |
||||
*.binlog |
||||
|
||||
# NVidia Nsight GPU debugger configuration file |
||||
*.nvuser |
||||
|
||||
# MFractors (Xamarin productivity tool) working folder |
||||
.mfractor/ |
||||
|
||||
### VisualStudio Patch ### |
||||
# By default, sensitive information, such as encrypted password |
||||
# should be stored in the .pubxml.user file. |
||||
*.pubxml.user |
||||
|
||||
# End of https://www.gitignore.io/api/visualstudio |
||||
@ -0,0 +1,34 @@
|
||||
language: cpp |
||||
|
||||
os: |
||||
- linux |
||||
- osx |
||||
|
||||
notifications: |
||||
email: |
||||
on_failure: change # default: always |
||||
|
||||
addons: |
||||
# Packages for Linux |
||||
apt: |
||||
packages: |
||||
- mingw-w64 |
||||
|
||||
env: |
||||
- MAKE_BUILD=make |
||||
- MAKE_BUILD=debug |
||||
|
||||
before_install: |
||||
# Packages for OSX |
||||
- if [ $TRAVIS_OS_NAME = osx ]; then brew install mingw-w64; fi |
||||
|
||||
before_script: |
||||
- touch storm.dll |
||||
- touch diabloui.dll |
||||
|
||||
script: |
||||
- if [ $MAKE_BUILD = make ]; then make; fi |
||||
- if [ $MAKE_BUILD = debug ]; then make debug; fi |
||||
|
||||
after_script: |
||||
- make clean |
||||
@ -0,0 +1,522 @@
|
||||
/*****************************************************************************/ |
||||
/* explode.cpp Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Implode function of PKWARE Data Compression library */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 11.03.03 1.00 Lad Splitted from Pkware.cpp */ |
||||
/* 08.04.03 1.01 Lad Renamed to explode.cpp to be compatible with pkware */ |
||||
/* 02.05.03 1.01 Lad Stress test done */ |
||||
/* 22.04.10 1.01 Lad Documented */ |
||||
/*****************************************************************************/ |
||||
|
||||
#include <assert.h> |
||||
#include <string.h> |
||||
|
||||
#include "pkware.h" |
||||
|
||||
#define PKDCL_OK 0 |
||||
#define PKDCL_STREAM_END 1 // All data from the input stream is read
|
||||
#define PKDCL_NEED_DICT 2 // Need more data (dictionary)
|
||||
#define PKDCL_CONTINUE 10 // Internal flag, not returned to user
|
||||
#define PKDCL_GET_INPUT 11 // Internal flag, not returned to user
|
||||
|
||||
static char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n" |
||||
"Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" |
||||
"Patent No. 5,051,745\r\n" |
||||
"PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" |
||||
"Version 1.11\r\n"; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tables
|
||||
|
||||
static unsigned char DistBits[] =
|
||||
{ |
||||
0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, |
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 |
||||
}; |
||||
|
||||
static unsigned char DistCode[] =
|
||||
{ |
||||
0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, |
||||
0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, |
||||
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, |
||||
0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 |
||||
}; |
||||
|
||||
static unsigned char ExLenBits[] = |
||||
{ |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 |
||||
}; |
||||
|
||||
static unsigned short LenBase[] = |
||||
{ |
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, |
||||
0x0008, 0x000A, 0x000E, 0x0016, 0x0026, 0x0046, 0x0086, 0x0106 |
||||
}; |
||||
|
||||
static unsigned char LenBits[] = |
||||
{ |
||||
0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 |
||||
}; |
||||
|
||||
static unsigned char LenCode[] = |
||||
{ |
||||
0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 |
||||
}; |
||||
|
||||
static unsigned char ChBitsAsc[] = |
||||
{ |
||||
0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, |
||||
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, |
||||
0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, |
||||
0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, |
||||
0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, |
||||
0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, |
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, |
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, |
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, |
||||
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D |
||||
}; |
||||
|
||||
static unsigned short ChCodeAsc[] =
|
||||
{ |
||||
0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, |
||||
0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, |
||||
0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, |
||||
0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, |
||||
0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, |
||||
0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, |
||||
0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, |
||||
0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, |
||||
0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, |
||||
0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, |
||||
0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, |
||||
0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, |
||||
0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, |
||||
0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, |
||||
0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, |
||||
0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, |
||||
0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, |
||||
0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, |
||||
0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, |
||||
0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, |
||||
0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, |
||||
0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, |
||||
0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, |
||||
0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, |
||||
0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, |
||||
0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, |
||||
0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, |
||||
0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, |
||||
0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, |
||||
0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, |
||||
0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, |
||||
0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
|
||||
}; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static void GenDecodeTabs( |
||||
unsigned char * positions, // [out] Table of positions
|
||||
unsigned char * start_indexes, // [in] Table of start indexes
|
||||
unsigned char * length_bits, // [in] Table of lengths. Each length is stored as number of bits
|
||||
size_t elements) // [in] Number of elements in start_indexes and length_bits
|
||||
{ |
||||
unsigned int index; |
||||
unsigned int length; |
||||
size_t i; |
||||
|
||||
for(i = 0; i < elements; i++) |
||||
{ |
||||
length = 1 << length_bits[i]; // Get the length in bytes
|
||||
|
||||
for(index = start_indexes[i]; index < 0x100; index += length) |
||||
{ |
||||
positions[index] = (unsigned char)i; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void GenAscTabs(TDcmpStruct * pWork) |
||||
{ |
||||
unsigned short * pChCodeAsc = &ChCodeAsc[0xFF]; |
||||
unsigned int acc, add; |
||||
unsigned short count; |
||||
|
||||
for(count = 0x00FF; pChCodeAsc >= ChCodeAsc; pChCodeAsc--, count--) |
||||
{ |
||||
unsigned char * pChBitsAsc = pWork->ChBitsAsc + count; |
||||
unsigned char bits_asc = *pChBitsAsc; |
||||
|
||||
if(bits_asc <= 8) |
||||
{ |
||||
add = (1 << bits_asc); |
||||
acc = *pChCodeAsc; |
||||
|
||||
do |
||||
{ |
||||
pWork->offs2C34[acc] = (unsigned char)count; |
||||
acc += add; |
||||
} |
||||
while(acc < 0x100); |
||||
} |
||||
else if((acc = (*pChCodeAsc & 0xFF)) != 0) |
||||
{ |
||||
pWork->offs2C34[acc] = 0xFF; |
||||
|
||||
if(*pChCodeAsc & 0x3F) |
||||
{ |
||||
bits_asc -= 4; |
||||
*pChBitsAsc = bits_asc; |
||||
|
||||
add = (1 << bits_asc); |
||||
acc = *pChCodeAsc >> 4; |
||||
do |
||||
{ |
||||
pWork->offs2D34[acc] = (unsigned char)count; |
||||
acc += add; |
||||
} |
||||
while(acc < 0x100); |
||||
} |
||||
else |
||||
{ |
||||
bits_asc -= 6; |
||||
*pChBitsAsc = bits_asc; |
||||
|
||||
add = (1 << bits_asc); |
||||
acc = *pChCodeAsc >> 6; |
||||
do |
||||
{ |
||||
pWork->offs2E34[acc] = (unsigned char)count; |
||||
acc += add; |
||||
} |
||||
while(acc < 0x80); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
bits_asc -= 8; |
||||
*pChBitsAsc = bits_asc; |
||||
|
||||
add = (1 << bits_asc); |
||||
acc = *pChCodeAsc >> 8; |
||||
do |
||||
{ |
||||
pWork->offs2EB4[acc] = (unsigned char)count; |
||||
acc += add; |
||||
} |
||||
while(acc < 0x100); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Removes given number of bits in the bit buffer. New bits are reloaded from
|
||||
// the input buffer, if needed.
|
||||
// Returns: PKDCL_OK: Operation was successful
|
||||
// PKDCL_STREAM_END: There are no more bits in the input buffer
|
||||
|
||||
static int WasteBits(TDcmpStruct * pWork, unsigned int nBits) |
||||
{ |
||||
// If number of bits required is less than number of (bits in the buffer) ?
|
||||
if(nBits <= pWork->extra_bits) |
||||
{ |
||||
pWork->extra_bits -= nBits; |
||||
pWork->bit_buff >>= nBits; |
||||
return PKDCL_OK; |
||||
} |
||||
|
||||
// Load input buffer if necessary
|
||||
pWork->bit_buff >>= pWork->extra_bits; |
||||
if(pWork->in_pos == pWork->in_bytes) |
||||
{ |
||||
pWork->in_pos = sizeof(pWork->in_buff); |
||||
if((pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param)) == 0) |
||||
return PKDCL_STREAM_END; |
||||
pWork->in_pos = 0; |
||||
} |
||||
|
||||
// Update bit buffer
|
||||
pWork->bit_buff |= (pWork->in_buff[pWork->in_pos++] << 8); |
||||
pWork->bit_buff >>= (nBits - pWork->extra_bits); |
||||
pWork->extra_bits = (pWork->extra_bits - nBits) + 8; |
||||
return PKDCL_OK; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Decodes next literal from the input (compressed) data.
|
||||
// Returns : 0x000: One byte 0x00
|
||||
// 0x001: One byte 0x01
|
||||
// ...
|
||||
// 0x0FF: One byte 0xFF
|
||||
// 0x100: Repetition, length of 0x02 bytes
|
||||
// 0x101: Repetition, length of 0x03 bytes
|
||||
// ...
|
||||
// 0x304: Repetition, length of 0x206 bytes
|
||||
// 0x305: End of stream
|
||||
// 0x306: Error
|
||||
|
||||
static unsigned int DecodeLit(TDcmpStruct * pWork) |
||||
{ |
||||
unsigned int extra_length_bits; // Number of bits of extra literal length
|
||||
unsigned int length_code; // Length code
|
||||
unsigned int value; |
||||
|
||||
// Test the current bit in byte buffer. If is not set, simply return the next 8 bits.
|
||||
if(pWork->bit_buff & 1) |
||||
{ |
||||
// Remove one bit from the input data
|
||||
if(WasteBits(pWork, 1)) |
||||
return 0x306;
|
||||
|
||||
// The next 8 bits hold the index to the length code table
|
||||
length_code = pWork->LengthCodes[pWork->bit_buff & 0xFF]; |
||||
|
||||
// Remove the apropriate number of bits
|
||||
if(WasteBits(pWork, pWork->LenBits[length_code])) |
||||
return 0x306; |
||||
|
||||
// Are there some extra bits for the obtained length code ?
|
||||
if((extra_length_bits = pWork->ExLenBits[length_code]) != 0) |
||||
{ |
||||
unsigned int extra_length = pWork->bit_buff & ((1 << extra_length_bits) - 1); |
||||
|
||||
if(WasteBits(pWork, extra_length_bits)) |
||||
{ |
||||
if((length_code + extra_length) != 0x10E) |
||||
return 0x306; |
||||
} |
||||
length_code = pWork->LenBase[length_code] + extra_length; |
||||
} |
||||
|
||||
// In order to distinguish uncompressed byte from repetition length,
|
||||
// we have to add 0x100 to the length.
|
||||
return length_code + 0x100; |
||||
} |
||||
|
||||
// Remove one bit from the input data
|
||||
if(WasteBits(pWork, 1)) |
||||
return 0x306; |
||||
|
||||
// If the binary compression type, read 8 bits and return them as one byte.
|
||||
if(pWork->ctype == CMP_BINARY) |
||||
{ |
||||
unsigned int uncompressed_byte = pWork->bit_buff & 0xFF; |
||||
|
||||
if(WasteBits(pWork, 8)) |
||||
return 0x306; |
||||
return uncompressed_byte; |
||||
} |
||||
|
||||
// When ASCII compression ...
|
||||
if(pWork->bit_buff & 0xFF) |
||||
{ |
||||
value = pWork->offs2C34[pWork->bit_buff & 0xFF]; |
||||
|
||||
if(value == 0xFF) |
||||
{ |
||||
if(pWork->bit_buff & 0x3F) |
||||
{ |
||||
if(WasteBits(pWork, 4)) |
||||
return 0x306; |
||||
|
||||
value = pWork->offs2D34[pWork->bit_buff & 0xFF]; |
||||
} |
||||
else |
||||
{ |
||||
if(WasteBits(pWork, 6)) |
||||
return 0x306; |
||||
|
||||
value = pWork->offs2E34[pWork->bit_buff & 0x7F]; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if(WasteBits(pWork, 8)) |
||||
return 0x306; |
||||
|
||||
value = pWork->offs2EB4[pWork->bit_buff & 0xFF]; |
||||
} |
||||
|
||||
return WasteBits(pWork, pWork->ChBitsAsc[value]) ? 0x306 : value; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Decodes the distance of the repetition, backwards relative to the
|
||||
// current output buffer position
|
||||
|
||||
static unsigned int DecodeDist(TDcmpStruct * pWork, unsigned int rep_length) |
||||
{ |
||||
unsigned int dist_pos_code; // Distance position code
|
||||
unsigned int dist_pos_bits; // Number of bits of distance position
|
||||
unsigned int distance; // Distance position
|
||||
|
||||
// Next 2-8 bits in the input buffer is the distance position code
|
||||
dist_pos_code = pWork->DistPosCodes[pWork->bit_buff & 0xFF]; |
||||
dist_pos_bits = pWork->DistBits[dist_pos_code]; |
||||
if(WasteBits(pWork, dist_pos_bits)) |
||||
return 0; |
||||
|
||||
if(rep_length == 2) |
||||
{ |
||||
// If the repetition is only 2 bytes length,
|
||||
// then take 2 bits from the stream in order to get the distance
|
||||
distance = (dist_pos_code << 2) | (pWork->bit_buff & 0x03); |
||||
if(WasteBits(pWork, 2)) |
||||
return 0; |
||||
} |
||||
else |
||||
{ |
||||
// If the repetition is more than 2 bytes length,
|
||||
// then take "dsize_bits" bits in order to get the distance
|
||||
distance = (dist_pos_code << pWork->dsize_bits) | (pWork->bit_buff & pWork->dsize_mask); |
||||
if(WasteBits(pWork, pWork->dsize_bits)) |
||||
return 0; |
||||
} |
||||
return distance + 1; |
||||
} |
||||
|
||||
static unsigned int Expand(TDcmpStruct * pWork) |
||||
{ |
||||
unsigned int next_literal; // Literal decoded from the compressed data
|
||||
unsigned int result; // Value to be returned
|
||||
unsigned int copyBytes; // Number of bytes to copy to the output buffer
|
||||
|
||||
pWork->outputPos = 0x1000; // Initialize output buffer position
|
||||
|
||||
// Decode the next literal from the input data.
|
||||
// The returned literal can either be an uncompressed byte (next_literal < 0x100)
|
||||
// or an encoded length of the repeating byte sequence that
|
||||
// is to be copied to the current buffer position
|
||||
while((result = next_literal = DecodeLit(pWork)) < 0x305) |
||||
{ |
||||
// If the literal is greater than 0x100, it holds length
|
||||
// of repeating byte sequence
|
||||
// literal of 0x100 means repeating sequence of 0x2 bytes
|
||||
// literal of 0x101 means repeating sequence of 0x3 bytes
|
||||
// ...
|
||||
// literal of 0x305 means repeating sequence of 0x207 bytes
|
||||
if(next_literal >= 0x100) |
||||
{ |
||||
unsigned char * source; |
||||
unsigned char * target; |
||||
unsigned int rep_length; // Length of the repetition, in bytes
|
||||
unsigned int minus_dist; // Backward distance to the repetition, relative to the current buffer position
|
||||
|
||||
// Get the length of the repeating sequence.
|
||||
// Note that the repeating block may overlap the current output position,
|
||||
// for example if there was a sequence of equal bytes
|
||||
rep_length = next_literal - 0xFE; |
||||
|
||||
// Get backward distance to the repetition
|
||||
if((minus_dist = DecodeDist(pWork, rep_length)) == 0) |
||||
{ |
||||
result = 0x306; |
||||
break; |
||||
} |
||||
|
||||
// Target and source pointer
|
||||
target = &pWork->out_buff[pWork->outputPos]; |
||||
source = target - minus_dist; |
||||
|
||||
// Update buffer output position
|
||||
pWork->outputPos += rep_length; |
||||
|
||||
// Copy the repeating sequence
|
||||
while(rep_length-- > 0) |
||||
*target++ = *source++; |
||||
} |
||||
else |
||||
{ |
||||
pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal; |
||||
} |
||||
|
||||
// Flush the output buffer, if number of extracted bytes has reached the end
|
||||
if(pWork->outputPos >= 0x2000) |
||||
{ |
||||
// Copy decompressed data into user buffer
|
||||
copyBytes = 0x1000; |
||||
pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); |
||||
|
||||
// Now copy the decompressed data to the first half of the buffer.
|
||||
// This is needed because the decompression might reuse them as repetitions.
|
||||
// Note that if the output buffer overflowed previously, the extra decompressed bytes
|
||||
// are stored in "out_buff_overflow", and they will now be
|
||||
// within decompressed part of the output buffer.
|
||||
memmove(pWork->out_buff, &pWork->out_buff[0x1000], pWork->outputPos - 0x1000); |
||||
pWork->outputPos -= 0x1000; |
||||
} |
||||
} |
||||
|
||||
// Flush any remaining decompressed bytes
|
||||
copyBytes = pWork->outputPos - 0x1000; |
||||
pWork->write_buf((char *)&pWork->out_buff[0x1000], ©Bytes, pWork->param); |
||||
return result; |
||||
} |
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main exploding function.
|
||||
|
||||
unsigned int explode( |
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), |
||||
void (*write_buf)(char *buf, unsigned int *size, void *param), |
||||
char *work_buf, |
||||
void *param) |
||||
{ |
||||
TDcmpStruct * pWork = (TDcmpStruct *)work_buf; |
||||
|
||||
// Initialize work struct and load compressed data
|
||||
// Note: The caller must zero the "work_buff" before passing it to explode
|
||||
pWork->read_buf = read_buf; |
||||
pWork->write_buf = write_buf; |
||||
pWork->param = param; |
||||
pWork->in_pos = sizeof(pWork->in_buff); |
||||
pWork->in_bytes = pWork->read_buf((char *)pWork->in_buff, &pWork->in_pos, pWork->param); |
||||
if(pWork->in_bytes <= 4) |
||||
return CMP_BAD_DATA; |
||||
|
||||
pWork->ctype = pWork->in_buff[0]; // Get the compression type (CMP_BINARY or CMP_ASCII)
|
||||
pWork->dsize_bits = pWork->in_buff[1]; // Get the dictionary size
|
||||
pWork->bit_buff = pWork->in_buff[2]; // Initialize 16-bit bit buffer
|
||||
pWork->extra_bits = 0; // Extra (over 8) bits
|
||||
pWork->in_pos = 3; // Position in input buffer
|
||||
|
||||
// Test for the valid dictionary size
|
||||
if(4 > pWork->dsize_bits || pWork->dsize_bits > 6)
|
||||
return CMP_INVALID_DICTSIZE; |
||||
|
||||
pWork->dsize_mask = 0xFFFF >> (0x10 - pWork->dsize_bits); // Shifted by 'sar' instruction
|
||||
|
||||
if(pWork->ctype != CMP_BINARY) |
||||
{ |
||||
if(pWork->ctype != CMP_ASCII) |
||||
return CMP_INVALID_MODE; |
||||
|
||||
memcpy(pWork->ChBitsAsc, ChBitsAsc, sizeof(pWork->ChBitsAsc)); |
||||
GenAscTabs(pWork); |
||||
} |
||||
|
||||
memcpy(pWork->LenBits, LenBits, sizeof(pWork->LenBits)); |
||||
GenDecodeTabs(pWork->LengthCodes, LenCode, pWork->LenBits, sizeof(pWork->LenBits)); |
||||
memcpy(pWork->ExLenBits, ExLenBits, sizeof(pWork->ExLenBits)); |
||||
memcpy(pWork->LenBase, LenBase, sizeof(pWork->LenBase)); |
||||
memcpy(pWork->DistBits, DistBits, sizeof(pWork->DistBits)); |
||||
GenDecodeTabs(pWork->DistPosCodes, DistCode, pWork->DistBits, sizeof(pWork->DistBits)); |
||||
if(Expand(pWork) != 0x306) |
||||
return CMP_NO_ERROR; |
||||
|
||||
return CMP_ABORT; |
||||
} |
||||
@ -0,0 +1,775 @@
|
||||
/*****************************************************************************/ |
||||
/* implode.cpp Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Implode function of PKWARE Data Compression library */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 11.04.03 1.00 Lad First version of implode.cpp */ |
||||
/* 02.05.03 1.00 Lad Stress test done */ |
||||
/* 22.04.10 1.01 Lad Documented */ |
||||
/*****************************************************************************/ |
||||
|
||||
#include <assert.h> |
||||
#include <string.h> |
||||
|
||||
#include "pkware.h" |
||||
|
||||
#if ((1200 < _MSC_VER) && (_MSC_VER < 1400)) |
||||
#pragma optimize("", off) |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define MAX_REP_LENGTH 0x204 // The longest allowed repetition
|
||||
|
||||
static char CopyrightPkware[] = "PKWARE Data Compression Library for Win32\r\n" |
||||
"Copyright 1989-1995 PKWARE Inc. All Rights Reserved\r\n" |
||||
"Patent No. 5,051,745\r\n" |
||||
"PKWARE Data Compression Library Reg. U.S. Pat. and Tm. Off.\r\n" |
||||
"Version 1.11\r\n"; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tables
|
||||
|
||||
static unsigned char DistBits[] =
|
||||
{ |
||||
0x02, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, |
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, |
||||
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 |
||||
}; |
||||
|
||||
static unsigned char DistCode[] =
|
||||
{ |
||||
0x03, 0x0D, 0x05, 0x19, 0x09, 0x11, 0x01, 0x3E, 0x1E, 0x2E, 0x0E, 0x36, 0x16, 0x26, 0x06, 0x3A, |
||||
0x1A, 0x2A, 0x0A, 0x32, 0x12, 0x22, 0x42, 0x02, 0x7C, 0x3C, 0x5C, 0x1C, 0x6C, 0x2C, 0x4C, 0x0C, |
||||
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04, 0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08, |
||||
0xF0, 0x70, 0xB0, 0x30, 0xD0, 0x50, 0x90, 0x10, 0xE0, 0x60, 0xA0, 0x20, 0xC0, 0x40, 0x80, 0x00 |
||||
}; |
||||
|
||||
static unsigned char ExLenBits[] = |
||||
{ |
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 |
||||
}; |
||||
|
||||
static unsigned char LenBits[] = |
||||
{ |
||||
0x03, 0x02, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07, 0x07 |
||||
}; |
||||
|
||||
static unsigned char LenCode[] = |
||||
{ |
||||
0x05, 0x03, 0x01, 0x06, 0x0A, 0x02, 0x0C, 0x14, 0x04, 0x18, 0x08, 0x30, 0x10, 0x20, 0x40, 0x00 |
||||
}; |
||||
|
||||
static unsigned char ChBitsAsc[] = |
||||
{ |
||||
0x0B, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x08, 0x07, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x04, 0x0A, 0x08, 0x0C, 0x0A, 0x0C, 0x0A, 0x08, 0x07, 0x07, 0x08, 0x09, 0x07, 0x06, 0x07, 0x08, |
||||
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x08, 0x08, 0x0C, 0x0B, 0x07, 0x09, 0x0B, |
||||
0x0C, 0x06, 0x07, 0x06, 0x06, 0x05, 0x07, 0x08, 0x08, 0x06, 0x0B, 0x09, 0x06, 0x07, 0x06, 0x06, |
||||
0x07, 0x0B, 0x06, 0x06, 0x06, 0x07, 0x09, 0x08, 0x09, 0x09, 0x0B, 0x08, 0x0B, 0x09, 0x0C, 0x08, |
||||
0x0C, 0x05, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06, 0x05, 0x0B, 0x07, 0x05, 0x06, 0x05, 0x05, |
||||
0x06, 0x0A, 0x05, 0x05, 0x05, 0x05, 0x08, 0x07, 0x08, 0x08, 0x0A, 0x0B, 0x0B, 0x0C, 0x0C, 0x0C, |
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, |
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, |
||||
0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, |
||||
0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x0D, |
||||
0x0D, 0x0D, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D |
||||
}; |
||||
|
||||
static unsigned short ChCodeAsc[] =
|
||||
{ |
||||
0x0490, 0x0FE0, 0x07E0, 0x0BE0, 0x03E0, 0x0DE0, 0x05E0, 0x09E0, |
||||
0x01E0, 0x00B8, 0x0062, 0x0EE0, 0x06E0, 0x0022, 0x0AE0, 0x02E0, |
||||
0x0CE0, 0x04E0, 0x08E0, 0x00E0, 0x0F60, 0x0760, 0x0B60, 0x0360, |
||||
0x0D60, 0x0560, 0x1240, 0x0960, 0x0160, 0x0E60, 0x0660, 0x0A60, |
||||
0x000F, 0x0250, 0x0038, 0x0260, 0x0050, 0x0C60, 0x0390, 0x00D8, |
||||
0x0042, 0x0002, 0x0058, 0x01B0, 0x007C, 0x0029, 0x003C, 0x0098, |
||||
0x005C, 0x0009, 0x001C, 0x006C, 0x002C, 0x004C, 0x0018, 0x000C, |
||||
0x0074, 0x00E8, 0x0068, 0x0460, 0x0090, 0x0034, 0x00B0, 0x0710, |
||||
0x0860, 0x0031, 0x0054, 0x0011, 0x0021, 0x0017, 0x0014, 0x00A8, |
||||
0x0028, 0x0001, 0x0310, 0x0130, 0x003E, 0x0064, 0x001E, 0x002E, |
||||
0x0024, 0x0510, 0x000E, 0x0036, 0x0016, 0x0044, 0x0030, 0x00C8, |
||||
0x01D0, 0x00D0, 0x0110, 0x0048, 0x0610, 0x0150, 0x0060, 0x0088, |
||||
0x0FA0, 0x0007, 0x0026, 0x0006, 0x003A, 0x001B, 0x001A, 0x002A, |
||||
0x000A, 0x000B, 0x0210, 0x0004, 0x0013, 0x0032, 0x0003, 0x001D, |
||||
0x0012, 0x0190, 0x000D, 0x0015, 0x0005, 0x0019, 0x0008, 0x0078, |
||||
0x00F0, 0x0070, 0x0290, 0x0410, 0x0010, 0x07A0, 0x0BA0, 0x03A0, |
||||
0x0240, 0x1C40, 0x0C40, 0x1440, 0x0440, 0x1840, 0x0840, 0x1040, |
||||
0x0040, 0x1F80, 0x0F80, 0x1780, 0x0780, 0x1B80, 0x0B80, 0x1380, |
||||
0x0380, 0x1D80, 0x0D80, 0x1580, 0x0580, 0x1980, 0x0980, 0x1180, |
||||
0x0180, 0x1E80, 0x0E80, 0x1680, 0x0680, 0x1A80, 0x0A80, 0x1280, |
||||
0x0280, 0x1C80, 0x0C80, 0x1480, 0x0480, 0x1880, 0x0880, 0x1080, |
||||
0x0080, 0x1F00, 0x0F00, 0x1700, 0x0700, 0x1B00, 0x0B00, 0x1300, |
||||
0x0DA0, 0x05A0, 0x09A0, 0x01A0, 0x0EA0, 0x06A0, 0x0AA0, 0x02A0, |
||||
0x0CA0, 0x04A0, 0x08A0, 0x00A0, 0x0F20, 0x0720, 0x0B20, 0x0320, |
||||
0x0D20, 0x0520, 0x0920, 0x0120, 0x0E20, 0x0620, 0x0A20, 0x0220, |
||||
0x0C20, 0x0420, 0x0820, 0x0020, 0x0FC0, 0x07C0, 0x0BC0, 0x03C0, |
||||
0x0DC0, 0x05C0, 0x09C0, 0x01C0, 0x0EC0, 0x06C0, 0x0AC0, 0x02C0, |
||||
0x0CC0, 0x04C0, 0x08C0, 0x00C0, 0x0F40, 0x0740, 0x0B40, 0x0340, |
||||
0x0300, 0x0D40, 0x1D00, 0x0D00, 0x1500, 0x0540, 0x0500, 0x1900, |
||||
0x0900, 0x0940, 0x1100, 0x0100, 0x1E00, 0x0E00, 0x0140, 0x1600, |
||||
0x0600, 0x1A00, 0x0E40, 0x0640, 0x0A40, 0x0A00, 0x1200, 0x0200, |
||||
0x1C00, 0x0C00, 0x1400, 0x0400, 0x1800, 0x0800, 0x1000, 0x0000
|
||||
}; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macros
|
||||
|
||||
// Macro for calculating hash of the current byte pair.
|
||||
// Note that most exact byte pair hash would be buffer[0] + buffer[1] << 0x08,
|
||||
// but even this way gives nice indication of equal byte pairs, with significantly
|
||||
// smaller size of the array that holds numbers of those hashes
|
||||
#define BYTE_PAIR_HASH(buffer) ((buffer[0] * 4) + (buffer[1] * 5)) |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
// Builds the "hash_to_index" table and "pair_hash_offsets" table.
|
||||
// Every element of "hash_to_index" will contain lowest index to the
|
||||
// "pair_hash_offsets" table, effectively giving offset of the first
|
||||
// occurence of the given PAIR_HASH in the input data.
|
||||
static void SortBuffer(TCmpStruct * pWork, unsigned char * buffer_begin, unsigned char * buffer_end) |
||||
{ |
||||
unsigned short * phash_to_index; |
||||
unsigned char * buffer_ptr; |
||||
unsigned short total_sum = 0; |
||||
unsigned long byte_pair_hash; // Hash value of the byte pair
|
||||
unsigned short byte_pair_offs; // Offset of the byte pair, relative to "work_buff"
|
||||
|
||||
// Zero the entire "phash_to_index" table
|
||||
memset(pWork->phash_to_index, 0, sizeof(pWork->phash_to_index)); |
||||
|
||||
// Step 1: Count amount of each PAIR_HASH in the input buffer
|
||||
// The table will look like this:
|
||||
// offs 0x000: Number of occurences of PAIR_HASH 0
|
||||
// offs 0x001: Number of occurences of PAIR_HASH 1
|
||||
// ...
|
||||
// offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 (the highest hash value)
|
||||
for(buffer_ptr = buffer_begin; buffer_ptr < buffer_end; buffer_ptr++) |
||||
pWork->phash_to_index[BYTE_PAIR_HASH(buffer_ptr)]++; |
||||
|
||||
// Step 2: Convert the table to the array of PAIR_HASH amounts.
|
||||
// Each element contains count of PAIR_HASHes that is less or equal
|
||||
// to element index
|
||||
// The table will look like this:
|
||||
// offs 0x000: Number of occurences of PAIR_HASH 0 or lower
|
||||
// offs 0x001: Number of occurences of PAIR_HASH 1 or lower
|
||||
// ...
|
||||
// offs 0x8F7: Number of occurences of PAIR_HASH 0x8F7 or lower
|
||||
for(phash_to_index = pWork->phash_to_index; phash_to_index < &pWork->phash_to_index_end; phash_to_index++) |
||||
{ |
||||
total_sum = total_sum + phash_to_index[0]; |
||||
phash_to_index[0] = total_sum; |
||||
} |
||||
|
||||
// Step 3: Convert the table to the array of indexes.
|
||||
// Now, each element contains index to the first occurence of given PAIR_HASH
|
||||
for(buffer_end--; buffer_end >= buffer_begin; buffer_end--) |
||||
{ |
||||
byte_pair_hash = BYTE_PAIR_HASH(buffer_end); |
||||
byte_pair_offs = (unsigned short)(buffer_end - pWork->work_buff); |
||||
|
||||
pWork->phash_to_index[byte_pair_hash]--; |
||||
pWork->phash_offs[pWork->phash_to_index[byte_pair_hash]] = byte_pair_offs; |
||||
} |
||||
} |
||||
|
||||
static void FlushBuf(TCmpStruct * pWork) |
||||
{ |
||||
unsigned char save_ch1; |
||||
unsigned char save_ch2; |
||||
unsigned int size = 0x800; |
||||
|
||||
pWork->write_buf(pWork->out_buff, &size, pWork->param); |
||||
|
||||
save_ch1 = pWork->out_buff[0x800]; |
||||
save_ch2 = pWork->out_buff[pWork->out_bytes]; |
||||
pWork->out_bytes -= 0x800; |
||||
|
||||
memset(pWork->out_buff, 0, sizeof(pWork->out_buff)); |
||||
|
||||
if(pWork->out_bytes != 0) |
||||
pWork->out_buff[0] = save_ch1; |
||||
if(pWork->out_bits != 0) |
||||
pWork->out_buff[pWork->out_bytes] = save_ch2; |
||||
} |
||||
|
||||
static void OutputBits(TCmpStruct * pWork, unsigned int nbits, unsigned long bit_buff) |
||||
{ |
||||
unsigned int out_bits; |
||||
|
||||
// If more than 8 bits to output, do recursion
|
||||
if(nbits > 8) |
||||
{ |
||||
OutputBits(pWork, 8, bit_buff); |
||||
bit_buff >>= 8; |
||||
nbits -= 8; |
||||
} |
||||
|
||||
// Add bits to the last out byte in out_buff;
|
||||
out_bits = pWork->out_bits; |
||||
pWork->out_buff[pWork->out_bytes] |= (unsigned char)(bit_buff << out_bits); |
||||
pWork->out_bits += nbits; |
||||
|
||||
// If 8 or more bits, increment number of bytes
|
||||
if(pWork->out_bits > 8) |
||||
{ |
||||
pWork->out_bytes++; |
||||
bit_buff >>= (8 - out_bits); |
||||
|
||||
pWork->out_buff[pWork->out_bytes] = (unsigned char)bit_buff; |
||||
pWork->out_bits &= 7; |
||||
} |
||||
else |
||||
{ |
||||
pWork->out_bits &= 7; |
||||
if(pWork->out_bits == 0) |
||||
pWork->out_bytes++; |
||||
} |
||||
|
||||
// If there is enough compressed bytes, flush them
|
||||
if(pWork->out_bytes >= 0x800) |
||||
FlushBuf(pWork); |
||||
} |
||||
|
||||
// This function searches for a repetition
|
||||
// (a previous occurence of the current byte sequence)
|
||||
// Returns length of the repetition, and stores the backward distance
|
||||
// to pWork structure.
|
||||
static unsigned int FindRep(TCmpStruct * pWork, unsigned char * input_data) |
||||
{ |
||||
unsigned short * phash_to_index; // Pointer into pWork->phash_to_index table
|
||||
unsigned short * phash_offs; // Pointer to the table containing offsets of each PAIR_HASH
|
||||
unsigned char * repetition_limit; // An eventual repetition must be at position below this pointer
|
||||
unsigned char * prev_repetition; // Pointer to the previous occurence of the current PAIR_HASH
|
||||
unsigned char * prev_rep_end; // End of the previous repetition
|
||||
unsigned char * input_data_ptr; |
||||
unsigned short phash_offs_index; // Index to the table with PAIR_HASH positions
|
||||
unsigned short min_phash_offs; // The lowest allowed hash offset
|
||||
unsigned short offs_in_rep; // Offset within found repetition
|
||||
unsigned int equal_byte_count; // Number of bytes that are equal to the previous occurence
|
||||
unsigned int rep_length = 1; // Length of the found repetition
|
||||
unsigned int rep_length2; // Secondary repetition
|
||||
unsigned char pre_last_byte; // Last but one byte from a repetion
|
||||
unsigned short di_val; |
||||
|
||||
// Calculate the previous position of the PAIR_HASH
|
||||
phash_to_index = pWork->phash_to_index + BYTE_PAIR_HASH(input_data); |
||||
min_phash_offs = (unsigned short)((input_data - pWork->work_buff) - pWork->dsize_bytes + 1); |
||||
phash_offs_index = phash_to_index[0]; |
||||
|
||||
// If the PAIR_HASH offset is below the limit, find a next one
|
||||
phash_offs = pWork->phash_offs + phash_offs_index; |
||||
if(*phash_offs < min_phash_offs) |
||||
{ |
||||
while(*phash_offs < min_phash_offs) |
||||
{ |
||||
phash_offs_index++; |
||||
phash_offs++; |
||||
} |
||||
*phash_to_index = phash_offs_index; |
||||
} |
||||
|
||||
// Get the first location of the PAIR_HASH,
|
||||
// and thus the first eventual location of byte repetition
|
||||
phash_offs = pWork->phash_offs + phash_offs_index; |
||||
prev_repetition = pWork->work_buff + phash_offs[0]; |
||||
repetition_limit = input_data - 1; |
||||
|
||||
// If the current PAIR_HASH was not encountered before,
|
||||
// we haven't found a repetition.
|
||||
if(prev_repetition >= repetition_limit) |
||||
return 0; |
||||
|
||||
// We have found a match of a PAIR_HASH. Now we have to make sure
|
||||
// that it is also a byte match, because PAIR_HASH is not unique.
|
||||
// We compare the bytes and count the length of the repetition
|
||||
input_data_ptr = input_data; |
||||
for(;;) |
||||
{ |
||||
// If the first byte of the repetition and the so-far-last byte
|
||||
// of the repetition are equal, we will compare the blocks.
|
||||
if(*input_data_ptr == *prev_repetition && input_data_ptr[rep_length-1] == prev_repetition[rep_length-1]) |
||||
{ |
||||
// Skip the current byte
|
||||
prev_repetition++; |
||||
input_data_ptr++; |
||||
equal_byte_count = 2; |
||||
|
||||
// Now count how many more bytes are equal
|
||||
while(equal_byte_count < MAX_REP_LENGTH) |
||||
{ |
||||
prev_repetition++; |
||||
input_data_ptr++; |
||||
|
||||
// Are the bytes different ?
|
||||
if(*prev_repetition != *input_data_ptr) |
||||
break; |
||||
|
||||
equal_byte_count++; |
||||
} |
||||
|
||||
// If we found a repetition of at least the same length, take it.
|
||||
// If there are multiple repetitions in the input buffer, this will
|
||||
// make sure that we find the most recent one, which in turn allows
|
||||
// us to store backward length in less amount of bits
|
||||
input_data_ptr = input_data; |
||||
if(equal_byte_count >= rep_length) |
||||
{ |
||||
// Calculate the backward distance of the repetition.
|
||||
// Note that the distance is stored as decremented by 1
|
||||
pWork->distance = (unsigned int)(input_data - prev_repetition + equal_byte_count - 1); |
||||
|
||||
// Repetitions longer than 10 bytes will be stored in more bits,
|
||||
// so they need a bit different handling
|
||||
if((rep_length = equal_byte_count) > 10) |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Move forward in the table of PAIR_HASH repetitions.
|
||||
// There might be a more recent occurence of the same repetition.
|
||||
phash_offs_index++; |
||||
phash_offs++; |
||||
prev_repetition = pWork->work_buff + phash_offs[0]; |
||||
|
||||
// If the next repetition is beyond the minimum allowed repetition, we are done.
|
||||
if(prev_repetition >= repetition_limit) |
||||
{ |
||||
// A repetition must have at least 2 bytes, otherwise it's not worth it
|
||||
return (rep_length >= 2) ? rep_length : 0; |
||||
} |
||||
} |
||||
|
||||
// If the repetition has max length of 0x204 bytes, we can't go any fuhrter
|
||||
if(equal_byte_count == MAX_REP_LENGTH) |
||||
{ |
||||
pWork->distance--; |
||||
return equal_byte_count; |
||||
} |
||||
|
||||
// Check for possibility of a repetition that occurs at more recent position
|
||||
phash_offs = pWork->phash_offs + phash_offs_index; |
||||
if(pWork->work_buff + phash_offs[1] >= repetition_limit) |
||||
return rep_length; |
||||
|
||||
//
|
||||
// The following part checks if there isn't a longer repetition at
|
||||
// a latter offset, that would lead to better compression.
|
||||
//
|
||||
// Example of data that can trigger this optimization:
|
||||
//
|
||||
// "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEQQQQQQQQQQQQ"
|
||||
// "XYZ"
|
||||
// "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ";
|
||||
//
|
||||
// Description of data in this buffer
|
||||
// [0x00] Single byte "E"
|
||||
// [0x01] Single byte "E"
|
||||
// [0x02] Repeat 0x1E bytes from [0x00]
|
||||
// [0x20] Single byte "X"
|
||||
// [0x21] Single byte "Y"
|
||||
// [0x22] Single byte "Z"
|
||||
// [0x23] 17 possible previous repetitions of length at least 0x10 bytes:
|
||||
// - Repetition of 0x10 bytes from [0x00] "EEEEEEEEEEEEEEEE"
|
||||
// - Repetition of 0x10 bytes from [0x01] "EEEEEEEEEEEEEEEE"
|
||||
// - Repetition of 0x10 bytes from [0x02] "EEEEEEEEEEEEEEEE"
|
||||
// ...
|
||||
// - Repetition of 0x10 bytes from [0x0F] "EEEEEEEEEEEEEEEE"
|
||||
// - Repetition of 0x1C bytes from [0x10] "EEEEEEEEEEEEEEEEQQQQQQQQQQQQ"
|
||||
// The last repetition is the best one.
|
||||
//
|
||||
|
||||
pWork->offs09BC[0] = 0xFFFF; |
||||
pWork->offs09BC[1] = 0x0000; |
||||
di_val = 0; |
||||
|
||||
// Note: I failed to figure out what does the table "offs09BC" mean.
|
||||
// If anyone has an idea, let me know to zezula_at_volny_dot_cz
|
||||
for(offs_in_rep = 1; offs_in_rep < rep_length; ) |
||||
{ |
||||
if(input_data[offs_in_rep] != input_data[di_val]) |
||||
{ |
||||
di_val = pWork->offs09BC[di_val]; |
||||
if(di_val != 0xFFFF) |
||||
continue; |
||||
} |
||||
pWork->offs09BC[++offs_in_rep] = ++di_val; |
||||
} |
||||
|
||||
//
|
||||
// Now go through all the repetitions from the first found one
|
||||
// to the current input data, and check if any of them migh be
|
||||
// a start of a greater sequence match.
|
||||
//
|
||||
|
||||
prev_repetition = pWork->work_buff + phash_offs[0]; |
||||
prev_rep_end = prev_repetition + rep_length; |
||||
rep_length2 = rep_length; |
||||
|
||||
for(;;) |
||||
{ |
||||
rep_length2 = pWork->offs09BC[rep_length2]; |
||||
if(rep_length2 == 0xFFFF) |
||||
rep_length2 = 0; |
||||
|
||||
// Get the pointer to the previous repetition
|
||||
phash_offs = pWork->phash_offs + phash_offs_index; |
||||
|
||||
// Skip those repetitions that don't reach the end
|
||||
// of the first found repetition
|
||||
do |
||||
{ |
||||
phash_offs++; |
||||
phash_offs_index++; |
||||
prev_repetition = pWork->work_buff + *phash_offs; |
||||
if(prev_repetition >= repetition_limit) |
||||
return rep_length; |
||||
} |
||||
while(prev_repetition + rep_length2 < prev_rep_end); |
||||
|
||||
// Verify if the last but one byte from the repetition matches
|
||||
// the last but one byte from the input data.
|
||||
// If not, find a next repetition
|
||||
pre_last_byte = input_data[rep_length - 2]; |
||||
if(pre_last_byte == prev_repetition[rep_length - 2]) |
||||
{ |
||||
// If the new repetition reaches beyond the end
|
||||
// of previously found repetition, reset the repetition length to zero.
|
||||
if(prev_repetition + rep_length2 != prev_rep_end) |
||||
{ |
||||
prev_rep_end = prev_repetition; |
||||
rep_length2 = 0; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
phash_offs = pWork->phash_offs + phash_offs_index; |
||||
do |
||||
{ |
||||
phash_offs++; |
||||
phash_offs_index++; |
||||
prev_repetition = pWork->work_buff + *phash_offs; |
||||
if(prev_repetition >= repetition_limit) |
||||
return rep_length; |
||||
} |
||||
while(prev_repetition[rep_length - 2] != pre_last_byte || prev_repetition[0] != input_data[0]); |
||||
|
||||
// Reset the length of the repetition to 2 bytes only
|
||||
prev_rep_end = prev_repetition + 2; |
||||
rep_length2 = 2; |
||||
} |
||||
|
||||
// Find out how many more characters are equal to the first repetition.
|
||||
while(*prev_rep_end == input_data[rep_length2]) |
||||
{ |
||||
if(++rep_length2 >= 0x204) |
||||
break; |
||||
prev_rep_end++; |
||||
} |
||||
|
||||
// Is the newly found repetion at least as long as the previous one ?
|
||||
if(rep_length2 >= rep_length) |
||||
{ |
||||
// Calculate the distance of the new repetition
|
||||
pWork->distance = (unsigned int)(input_data - prev_repetition - 1); |
||||
if((rep_length = rep_length2) == 0x204) |
||||
return rep_length; |
||||
|
||||
// Update the additional elements in the "offs09BC" table
|
||||
// to reflect new rep length
|
||||
while(offs_in_rep < rep_length2) |
||||
{ |
||||
if(input_data[offs_in_rep] != input_data[di_val]) |
||||
{ |
||||
di_val = pWork->offs09BC[di_val]; |
||||
if(di_val != 0xFFFF) |
||||
continue; |
||||
} |
||||
pWork->offs09BC[++offs_in_rep] = ++di_val; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void WriteCmpData(TCmpStruct * pWork) |
||||
{ |
||||
unsigned char * input_data_end; // Pointer to the end of the input data
|
||||
unsigned char * input_data = pWork->work_buff + pWork->dsize_bytes + 0x204; |
||||
unsigned int input_data_ended = 0; // If 1, then all data from the input stream have been already loaded
|
||||
unsigned int save_rep_length; // Saved length of current repetition
|
||||
unsigned int save_distance = 0; // Saved distance of current repetition
|
||||
unsigned int rep_length; // Length of the found repetition
|
||||
unsigned int phase = 0; //
|
||||
|
||||
// Store the compression type and dictionary size
|
||||
pWork->out_buff[0] = (char)pWork->ctype; |
||||
pWork->out_buff[1] = (char)pWork->dsize_bits; |
||||
pWork->out_bytes = 2; |
||||
|
||||
// Reset output buffer to zero
|
||||
memset(&pWork->out_buff[2], 0, sizeof(pWork->out_buff) - 2); |
||||
pWork->out_bits = 0; |
||||
|
||||
while(input_data_ended == 0) |
||||
{ |
||||
unsigned int bytes_to_load = 0x1000; |
||||
int total_loaded = 0; |
||||
int bytes_loaded; |
||||
|
||||
// Load the bytes from the input stream, up to 0x1000 bytes
|
||||
while(bytes_to_load != 0) |
||||
{ |
||||
bytes_loaded = pWork->read_buf((char *)pWork->work_buff + pWork->dsize_bytes + 0x204 + total_loaded, |
||||
&bytes_to_load, |
||||
pWork->param); |
||||
if(bytes_loaded == 0) |
||||
{ |
||||
if(total_loaded == 0 && phase == 0) |
||||
goto __Exit; |
||||
input_data_ended = 1; |
||||
break; |
||||
} |
||||
else |
||||
{ |
||||
bytes_to_load -= bytes_loaded; |
||||
total_loaded += bytes_loaded; |
||||
} |
||||
} |
||||
|
||||
input_data_end = pWork->work_buff + pWork->dsize_bytes + total_loaded; |
||||
if(input_data_ended) |
||||
input_data_end += 0x204; |
||||
|
||||
//
|
||||
// Warning: The end of the buffer passed to "SortBuffer" is actually 2 bytes beyond
|
||||
// valid data. It is questionable if this is actually a bug or not,
|
||||
// but it might cause the compressed data output to be dependent on random bytes
|
||||
// that are in the buffer.
|
||||
// To prevent that, the calling application must always zero the compression
|
||||
// buffer before passing it to "implode"
|
||||
//
|
||||
|
||||
// Search the PAIR_HASHes of the loaded blocks. Also, include
|
||||
// previously compressed data, if any.
|
||||
switch(phase) |
||||
{ |
||||
case 0:
|
||||
SortBuffer(pWork, input_data, input_data_end + 1); |
||||
phase++; |
||||
if(pWork->dsize_bytes != 0x1000) |
||||
phase++; |
||||
break; |
||||
|
||||
case 1: |
||||
SortBuffer(pWork, input_data - pWork->dsize_bytes + 0x204, input_data_end + 1); |
||||
phase++; |
||||
break; |
||||
|
||||
default: |
||||
SortBuffer(pWork, input_data - pWork->dsize_bytes, input_data_end + 1); |
||||
break; |
||||
} |
||||
|
||||
// Perform the compression of the current block
|
||||
while(input_data < input_data_end) |
||||
{ |
||||
// Find if the current byte sequence wasn't there before.
|
||||
rep_length = FindRep(pWork, input_data); |
||||
while(rep_length != 0) |
||||
{ |
||||
// If we found repetition of 2 bytes, that is 0x100 or fuhrter back,
|
||||
// don't bother. Storing the distance of 0x100 bytes would actually
|
||||
// take more space than storing the 2 bytes as-is.
|
||||
if(rep_length == 2 && pWork->distance >= 0x100) |
||||
break; |
||||
|
||||
// When we are at the end of the input data, we cannot allow
|
||||
// the repetition to go past the end of the input data.
|
||||
if(input_data_ended && input_data + rep_length > input_data_end) |
||||
{ |
||||
// Shorten the repetition length so that it only covers valid data
|
||||
rep_length = (unsigned long)(input_data_end - input_data); |
||||
if(rep_length < 2) |
||||
break; |
||||
|
||||
// If we got repetition of 2 bytes, that is 0x100 or more backward, don't bother
|
||||
if(rep_length == 2 && pWork->distance >= 0x100) |
||||
break; |
||||
goto __FlushRepetition; |
||||
} |
||||
|
||||
if(rep_length >= 8 || input_data + 1 >= input_data_end) |
||||
goto __FlushRepetition; |
||||
|
||||
// Try to find better repetition 1 byte later.
|
||||
// Example: "ARROCKFORT" "AROCKFORT"
|
||||
// When "input_data" points to the second string, FindRep
|
||||
// returns the occurence of "AR". But there is longer repetition "ROCKFORT",
|
||||
// beginning 1 byte after.
|
||||
save_rep_length = rep_length; |
||||
save_distance = pWork->distance; |
||||
rep_length = FindRep(pWork, input_data + 1); |
||||
|
||||
// Only use the new repetition if it's length is greater than the previous one
|
||||
if(rep_length > save_rep_length) |
||||
{ |
||||
// If the new repetition if only 1 byte better
|
||||
// and the previous distance is less than 0x80 bytes, use the previous repetition
|
||||
if(rep_length > save_rep_length + 1 || save_distance > 0x80) |
||||
{ |
||||
// Flush one byte, so that input_data will point to the secondary repetition
|
||||
OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); |
||||
input_data++; |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
// Revert to the previous repetition
|
||||
rep_length = save_rep_length; |
||||
pWork->distance = save_distance; |
||||
|
||||
__FlushRepetition: |
||||
|
||||
OutputBits(pWork, pWork->nChBits[rep_length + 0xFE], pWork->nChCodes[rep_length + 0xFE]); |
||||
if(rep_length == 2) |
||||
{ |
||||
OutputBits(pWork, pWork->dist_bits[pWork->distance >> 2], |
||||
pWork->dist_codes[pWork->distance >> 2]); |
||||
OutputBits(pWork, 2, pWork->distance & 3); |
||||
} |
||||
else |
||||
{ |
||||
OutputBits(pWork, pWork->dist_bits[pWork->distance >> pWork->dsize_bits], |
||||
pWork->dist_codes[pWork->distance >> pWork->dsize_bits]); |
||||
OutputBits(pWork, pWork->dsize_bits, pWork->dsize_mask & pWork->distance); |
||||
} |
||||
|
||||
// Move the begin of the input data by the length of the repetition
|
||||
input_data += rep_length; |
||||
goto _00402252; |
||||
} |
||||
|
||||
// If there was no previous repetition for the current position in the input data,
|
||||
// just output the 9-bit literal for the one character
|
||||
OutputBits(pWork, pWork->nChBits[*input_data], pWork->nChCodes[*input_data]); |
||||
input_data++; |
||||
_00402252:; |
||||
} |
||||
|
||||
if(input_data_ended == 0) |
||||
{ |
||||
input_data -= 0x1000; |
||||
memmove(pWork->work_buff, pWork->work_buff + 0x1000, pWork->dsize_bytes + 0x204); |
||||
} |
||||
} |
||||
|
||||
__Exit: |
||||
|
||||
// Write the termination literal
|
||||
OutputBits(pWork, pWork->nChBits[0x305], pWork->nChCodes[0x305]); |
||||
if(pWork->out_bits != 0) |
||||
pWork->out_bytes++; |
||||
pWork->write_buf(pWork->out_buff, &pWork->out_bytes, pWork->param); |
||||
return; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Main imploding function
|
||||
|
||||
unsigned int PKEXPORT implode( |
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), |
||||
void (*write_buf)(char *buf, unsigned int *size, void *param), |
||||
char *work_buf, |
||||
void *param, |
||||
unsigned int *type, |
||||
unsigned int *dsize) |
||||
{ |
||||
TCmpStruct * pWork = (TCmpStruct *)work_buf; |
||||
unsigned int nChCode; |
||||
unsigned int nCount; |
||||
unsigned int i; |
||||
int nCount2; |
||||
|
||||
// Fill the work buffer information
|
||||
// Note: The caller must zero the "work_buff" before passing it to implode
|
||||
pWork->read_buf = read_buf; |
||||
pWork->write_buf = write_buf; |
||||
pWork->dsize_bytes = *dsize; |
||||
pWork->ctype = *type; |
||||
pWork->param = param; |
||||
pWork->dsize_bits = 4; |
||||
pWork->dsize_mask = 0x0F; |
||||
|
||||
// Test dictionary size
|
||||
switch(*dsize) |
||||
{ |
||||
case CMP_IMPLODE_DICT_SIZE3: // 0x1000 bytes
|
||||
pWork->dsize_bits++; |
||||
pWork->dsize_mask |= 0x20; |
||||
// No break here !!!
|
||||
|
||||
case CMP_IMPLODE_DICT_SIZE2: // 0x800 bytes
|
||||
pWork->dsize_bits++; |
||||
pWork->dsize_mask |= 0x10; |
||||
// No break here !!!
|
||||
|
||||
case CMP_IMPLODE_DICT_SIZE1: // 0x400
|
||||
break; |
||||
|
||||
default: |
||||
return CMP_INVALID_DICTSIZE; |
||||
} |
||||
|
||||
// Test the compression type
|
||||
switch(*type) |
||||
{ |
||||
case CMP_BINARY: // We will compress data with binary compression type
|
||||
for(nChCode = 0, nCount = 0; nCount < 0x100; nCount++) |
||||
{ |
||||
pWork->nChBits[nCount] = 9; |
||||
pWork->nChCodes[nCount] = (unsigned short)nChCode; |
||||
nChCode = (nChCode & 0x0000FFFF) + 2; |
||||
} |
||||
break; |
||||
|
||||
|
||||
case CMP_ASCII: // We will compress data with ASCII compression type
|
||||
for(nCount = 0; nCount < 0x100; nCount++) |
||||
{ |
||||
pWork->nChBits[nCount] = (unsigned char )(ChBitsAsc[nCount] + 1); |
||||
pWork->nChCodes[nCount] = (unsigned short)(ChCodeAsc[nCount] * 2); |
||||
} |
||||
break; |
||||
|
||||
default: |
||||
return CMP_INVALID_MODE; |
||||
} |
||||
|
||||
for(i = 0; i < 0x10; i++) |
||||
{ |
||||
if(1 << ExLenBits[i]) |
||||
{ |
||||
for(nCount2 = 0; nCount2 < (1 << ExLenBits[i]); nCount2++) |
||||
{ |
||||
pWork->nChBits[nCount] = (unsigned char)(ExLenBits[i] + LenBits[i] + 1); |
||||
pWork->nChCodes[nCount] = (unsigned short)((nCount2 << (LenBits[i] + 1)) | ((LenCode[i] & 0xFFFF00FF) * 2) | 1); |
||||
nCount++; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Copy the distance codes and distance bits and perform the compression
|
||||
memcpy(&pWork->dist_codes, DistCode, sizeof(DistCode)); |
||||
memcpy(&pWork->dist_bits, DistBits, sizeof(DistBits)); |
||||
WriteCmpData(pWork); |
||||
return CMP_NO_ERROR; |
||||
} |
||||
@ -0,0 +1,142 @@
|
||||
/*****************************************************************************/ |
||||
/* pkware.h Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Header file for PKWARE Data Compression Library */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 31.03.03 1.00 Lad The first version of pkware.h */ |
||||
/*****************************************************************************/ |
||||
|
||||
#ifndef __PKWARE_H__ |
||||
#define __PKWARE_H__ |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
#define CMP_BINARY 0 // Binary compression
|
||||
#define CMP_ASCII 1 // Ascii compression
|
||||
|
||||
#define CMP_NO_ERROR 0 |
||||
#define CMP_INVALID_DICTSIZE 1 |
||||
#define CMP_INVALID_MODE 2 |
||||
#define CMP_BAD_DATA 3 |
||||
#define CMP_ABORT 4 |
||||
|
||||
#define CMP_IMPLODE_DICT_SIZE1 1024 // Dictionary size of 1024
|
||||
#define CMP_IMPLODE_DICT_SIZE2 2048 // Dictionary size of 2048
|
||||
#define CMP_IMPLODE_DICT_SIZE3 4096 // Dictionary size of 4096
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Define calling convention
|
||||
|
||||
#ifndef PKEXPORT |
||||
#ifdef WIN32 |
||||
#define PKEXPORT __cdecl // Use for normal __cdecl calling
|
||||
#else |
||||
#define PKEXPORT |
||||
#endif |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal structures
|
||||
|
||||
// Compression structure
|
||||
typedef struct |
||||
{ |
||||
unsigned int distance; // 0000: Backward distance of the currently found repetition, decreased by 1
|
||||
unsigned int out_bytes; // 0004: # bytes available in out_buff
|
||||
unsigned int out_bits; // 0008: # of bits available in the last out byte
|
||||
unsigned int dsize_bits; // 000C: Number of bits needed for dictionary size. 4 = 0x400, 5 = 0x800, 6 = 0x1000
|
||||
unsigned int dsize_mask; // 0010: Bit mask for dictionary. 0x0F = 0x400, 0x1F = 0x800, 0x3F = 0x1000
|
||||
unsigned int ctype; // 0014: Compression type (CMP_ASCII or CMP_BINARY)
|
||||
unsigned int dsize_bytes; // 0018: Dictionary size in bytes
|
||||
unsigned char dist_bits[0x40]; // 001C: Distance bits
|
||||
unsigned char dist_codes[0x40]; // 005C: Distance codes
|
||||
unsigned char nChBits[0x306]; // 009C: Table of literal bit lengths to be put to the output stream
|
||||
unsigned short nChCodes[0x306]; // 03A2: Table of literal codes to be put to the output stream
|
||||
unsigned short offs09AE; // 09AE:
|
||||
|
||||
void * param; // 09B0: User parameter
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // 9B4
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param); // 9B8
|
||||
|
||||
unsigned short offs09BC[0x204]; // 09BC:
|
||||
unsigned long offs0DC4; // 0DC4:
|
||||
unsigned short phash_to_index[0x900]; // 0DC8: Array of indexes (one for each PAIR_HASH) to the "pair_hash_offsets" table
|
||||
unsigned short phash_to_index_end; // 1FC8: End marker for "phash_to_index" table
|
||||
char out_buff[0x802]; // 1FCA: Compressed data
|
||||
unsigned char work_buff[0x2204]; // 27CC: Work buffer
|
||||
// + DICT_OFFSET => Dictionary
|
||||
// + UNCMP_OFFSET => Uncompressed data
|
||||
unsigned short phash_offs[0x2204]; // 49D0: Table of offsets for each PAIR_HASH
|
||||
} TCmpStruct; |
||||
|
||||
#define CMP_BUFFER_SIZE sizeof(TCmpStruct) // Size of compression structure.
|
||||
// Defined as 36312 in pkware header file
|
||||
|
||||
|
||||
// Decompression structure
|
||||
typedef struct |
||||
{ |
||||
unsigned long offs0000; // 0000
|
||||
unsigned long ctype; // 0004: Compression type (CMP_BINARY or CMP_ASCII)
|
||||
unsigned long outputPos; // 0008: Position in output buffer
|
||||
unsigned long dsize_bits; // 000C: Dict size (4, 5, 6 for 0x400, 0x800, 0x1000)
|
||||
unsigned long dsize_mask; // 0010: Dict size bitmask (0x0F, 0x1F, 0x3F for 0x400, 0x800, 0x1000)
|
||||
unsigned long bit_buff; // 0014: 16-bit buffer for processing input data
|
||||
unsigned long extra_bits; // 0018: Number of extra (above 8) bits in bit buffer
|
||||
unsigned int in_pos; // 001C: Position in in_buff
|
||||
unsigned long in_bytes; // 0020: Number of bytes in input buffer
|
||||
void * param; // 0024: Custom parameter
|
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param); // Pointer to function that reads data from the input stream
|
||||
void (*write_buf)(char *buf, unsigned int *size, void *param);// Pointer to function that writes data to the output stream
|
||||
|
||||
unsigned char out_buff[0x2204]; // 0030: Output circle buffer.
|
||||
// 0x0000 - 0x0FFF: Previous uncompressed data, kept for repetitions
|
||||
// 0x1000 - 0x1FFF: Currently decompressed data
|
||||
// 0x2000 - 0x2203: Reserve space for the longest possible repetition
|
||||
unsigned char in_buff[0x800]; // 2234: Buffer for data to be decompressed
|
||||
unsigned char DistPosCodes[0x100]; // 2A34: Table of distance position codes
|
||||
unsigned char LengthCodes[0x100]; // 2B34: Table of length codes
|
||||
unsigned char offs2C34[0x100]; // 2C34: Buffer for
|
||||
unsigned char offs2D34[0x100]; // 2D34: Buffer for
|
||||
unsigned char offs2E34[0x80]; // 2EB4: Buffer for
|
||||
unsigned char offs2EB4[0x100]; // 2EB4: Buffer for
|
||||
unsigned char ChBitsAsc[0x100]; // 2FB4: Buffer for
|
||||
unsigned char DistBits[0x40]; // 30B4: Numbers of bytes to skip copied block length
|
||||
unsigned char LenBits[0x10]; // 30F4: Numbers of bits for skip copied block length
|
||||
unsigned char ExLenBits[0x10]; // 3104: Number of valid bits for copied block
|
||||
unsigned short LenBase[0x10]; // 3114: Buffer for
|
||||
} TDcmpStruct; |
||||
|
||||
#define EXP_BUFFER_SIZE sizeof(TDcmpStruct) // Size of decompression structure
|
||||
// Defined as 12596 in pkware headers
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
unsigned int PKEXPORT implode( |
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), |
||||
void (*write_buf)(char *buf, unsigned int *size, void *param), |
||||
char *work_buf, |
||||
void *param, |
||||
unsigned int *type, |
||||
unsigned int *dsize); |
||||
|
||||
|
||||
unsigned int PKEXPORT explode( |
||||
unsigned int (*read_buf)(char *buf, unsigned int *size, void *param), |
||||
void (*write_buf)(char *buf, unsigned int *size, void *param), |
||||
char *work_buf, |
||||
void *param); |
||||
|
||||
#ifdef __cplusplus |
||||
} // End of 'extern "C"' declaration
|
||||
#endif |
||||
|
||||
#endif // __PKWARE_H__
|
||||
@ -0,0 +1,93 @@
|
||||
# Microsoft Developer Studio Project File - Name="Storm" - Package Owner=<4> |
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
# ** DO NOT EDIT ** |
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 |
||||
|
||||
CFG=Storm - Win32 Debug |
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
!MESSAGE use the Export Makefile command and run |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "Storm.mak". |
||||
!MESSAGE |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "Storm.mak" CFG="Storm - Win32 Debug" |
||||
!MESSAGE |
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE |
||||
!MESSAGE "Storm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") |
||||
!MESSAGE "Storm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") |
||||
!MESSAGE |
||||
|
||||
# Begin Project |
||||
# PROP AllowPerConfigDependencies 0 |
||||
# PROP Scc_ProjName "" |
||||
# PROP Scc_LocalPath "" |
||||
CPP=cl.exe |
||||
MTL=midl.exe |
||||
RSC=rc.exe |
||||
|
||||
!IF "$(CFG)" == "Storm - Win32 Release" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "WinRel" |
||||
# PROP BASE Intermediate_Dir "WinRel" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "WinRel" |
||||
# PROP Intermediate_Dir "WinRel" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 |
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"storm.def" |
||||
|
||||
!ELSEIF "$(CFG)" == "Storm - Win32 Debug" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 1 |
||||
# PROP BASE Output_Dir "WinDebug" |
||||
# PROP BASE Intermediate_Dir "WinDebug" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 1 |
||||
# PROP Output_Dir "WinDebug" |
||||
# PROP Intermediate_Dir "WinDebug" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /O1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" |
||||
# ADD RSC /l 0x409 /d "_DEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept |
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:"storm.def" /pdbtype:sept |
||||
|
||||
!ENDIF |
||||
|
||||
# Begin Target |
||||
|
||||
# Name "Storm - Win32 Release" |
||||
# Name "Storm - Win32 Debug" |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\storm.cpp |
||||
# End Source File |
||||
# End Target |
||||
# End Project |
||||
@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup Label="ProjectConfigurations"> |
||||
<ProjectConfiguration Include="Debug|Win32"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|Win32"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
</ItemGroup> |
||||
<PropertyGroup Label="Globals"> |
||||
<SccProjectName /> |
||||
<SccLocalPath /> |
||||
<ProjectGuid>{B28F69CE-15A1-424D-BBB5-2727258D675B}</ProjectGuid> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
<PlatformToolset>v141</PlatformToolset> |
||||
<UseOfMfc>false</UseOfMfc> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
<PlatformToolset>v141</PlatformToolset> |
||||
<UseOfMfc>false</UseOfMfc> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
<ImportGroup Label="ExtensionSettings"> |
||||
</ImportGroup> |
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> |
||||
</ImportGroup> |
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> |
||||
</ImportGroup> |
||||
<PropertyGroup Label="UserMacros" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<OutDir>.\WinRel\</OutDir> |
||||
<IntDir>.\WinRel\</IntDir> |
||||
<LinkIncremental>false</LinkIncremental> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<OutDir>.\WinDebug\</OutDir> |
||||
<IntDir>.\WinDebug\</IntDir> |
||||
<LinkIncremental>true</LinkIncremental> |
||||
</PropertyGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<ClCompile> |
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion> |
||||
<StringPooling>true</StringPooling> |
||||
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
<Optimization>MaxSpeed</Optimization> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<AssemblerListingLocation>.\WinRel\</AssemblerListingLocation> |
||||
<PrecompiledHeaderOutputFile>.\WinRel\Storm.pch</PrecompiledHeaderOutputFile> |
||||
<ObjectFileName>.\WinRel\</ObjectFileName> |
||||
<ProgramDataBaseFileName>.\WinRel\</ProgramDataBaseFileName> |
||||
</ClCompile> |
||||
<Midl> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<TypeLibraryName>.\WinRel\Storm.tlb</TypeLibraryName> |
||||
<MkTypLibCompatible>true</MkTypLibCompatible> |
||||
<RedirectOutputAndErrors>NUL</RedirectOutputAndErrors> |
||||
<TargetEnvironment>Win32</TargetEnvironment> |
||||
</Midl> |
||||
<ResourceCompile> |
||||
<Culture>0x0409</Culture> |
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
</ResourceCompile> |
||||
<Bscmake> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<OutputFile>.\WinRel\Storm.bsc</OutputFile> |
||||
</Bscmake> |
||||
<Link> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<LinkDLL>true</LinkDLL> |
||||
<SubSystem>Windows</SubSystem> |
||||
<ModuleDefinitionFile>storm.def</ModuleDefinitionFile> |
||||
<OutputFile>.\WinRel\Storm.dll</OutputFile> |
||||
<ImportLibrary>.\WinRel\Storm.lib</ImportLibrary> |
||||
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<ClCompile> |
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion> |
||||
<Optimization>Disabled</Optimization> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<MinimalRebuild>true</MinimalRebuild> |
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat> |
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<AssemblerListingLocation>.\WinDebug\</AssemblerListingLocation> |
||||
<PrecompiledHeaderOutputFile>.\WinDebug\Storm.pch</PrecompiledHeaderOutputFile> |
||||
<ObjectFileName>.\WinDebug\</ObjectFileName> |
||||
<ProgramDataBaseFileName>.\WinDebug\</ProgramDataBaseFileName> |
||||
</ClCompile> |
||||
<Midl> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<TypeLibraryName>.\WinDebug\Storm.tlb</TypeLibraryName> |
||||
<MkTypLibCompatible>true</MkTypLibCompatible> |
||||
<RedirectOutputAndErrors>NUL</RedirectOutputAndErrors> |
||||
<TargetEnvironment>Win32</TargetEnvironment> |
||||
</Midl> |
||||
<ResourceCompile> |
||||
<Culture>0x0409</Culture> |
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
</ResourceCompile> |
||||
<Bscmake> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<OutputFile>.\WinDebug\Storm.bsc</OutputFile> |
||||
</Bscmake> |
||||
<Link> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<LinkDLL>true</LinkDLL> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
<SubSystem>Windows</SubSystem> |
||||
<ModuleDefinitionFile>storm.def</ModuleDefinitionFile> |
||||
<OutputFile>.\WinDebug\Storm.dll</OutputFile> |
||||
<ImportLibrary>.\WinDebug\Storm.lib</ImportLibrary> |
||||
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemGroup> |
||||
<ClCompile Include="storm.cpp" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="storm.def" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ClInclude Include="storm.h" /> |
||||
</ItemGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
<ImportGroup Label="ExtensionTargets"> |
||||
</ImportGroup> |
||||
</Project> |
||||
@ -0,0 +1,238 @@
|
||||
#include "storm.h" |
||||
|
||||
#define rBool { return TRUE; } |
||||
#define rPVoid { return NULL; } |
||||
#define rVoid { return; } |
||||
#define rInt { return 0; } |
||||
|
||||
BOOL STORMAPI SNetCreateGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID) rBool; |
||||
BOOL STORMAPI SNetDestroy() rBool; |
||||
BOOL STORMAPI SNetEnumProviders(int (STORMAPI *callback)(DWORD, DWORD, DWORD, DWORD), int mincaps) rBool; |
||||
|
||||
BOOL STORMAPI SNetEnumGames(int (STORMAPI *callback)(DWORD, DWORD, DWORD), int *hintnextcall) rBool; |
||||
BOOL STORMAPI SNetDropPlayer(int playerid, DWORD flags) rBool; |
||||
BOOL STORMAPI SNetGetGameInfo(int type, void *dst, size_t length, size_t *byteswritten) rBool; |
||||
|
||||
BOOL STORMAPI SNetGetNumPlayers(int *firstplayerid, int *lastplayerid, int *activeplayers) rBool; |
||||
|
||||
BOOL STORMAPI SNetGetPlayerCaps(char playerid, PCAPS playerCaps) rBool; |
||||
BOOL STORMAPI SNetGetPlayerName(int playerid, char *buffer, size_t buffersize) rBool; |
||||
//BOOL STORMAPI SNetGetProviderCaps(PCAPS providerCaps) rBool;
|
||||
BOOL STORMAPI SNetGetTurnsInTransit(int *turns) rBool; |
||||
BOOL STORMAPI SNetInitializeDevice(int a1, int a2, int a3, int a4, int *a5) rBool; |
||||
//BOOL STORMAPI SNetInitializeProvider(DWORD providerName, client_info *gameClientInfo, user_info *userData, battle_info *bnCallbacks, module_info *moduleData) rBool;
|
||||
BOOL STORMAPI SNetJoinGame(int id, char *gameName, char *gamePassword, char *playerName, char *userStats, int *playerid) rBool; |
||||
BOOL STORMAPI SNetLeaveGame(int type) rBool; |
||||
BOOL STORMAPI SNetPerformUpgrade(DWORD *upgradestatus) rBool; |
||||
BOOL STORMAPI SNetReceiveMessage(int *senderplayerid, char **data, int *databytes) rBool; |
||||
BOOL STORMAPI SNetReceiveTurns(int a1, int arraysize, char **arraydata, unsigned int *arraydatabytes, DWORD *arrayplayerstatus) rBool; |
||||
//HANDLE STORMAPI SNetRegisterEventHandler(int type, void (STORMAPI *sEvent)(PS_EVT)) rPVoid;
|
||||
|
||||
int STORMAPI SNetSelectGame(int a1, int a2, int a3, int a4, int a5, int *playerid) rInt; |
||||
|
||||
BOOL STORMAPI SNetSendMessage(int playerID, void *data, size_t databytes) rBool; |
||||
BOOL STORMAPI SNetSendTurn(char *data, size_t databytes) rBool; |
||||
|
||||
BOOL STORMAPI SNetSetGameMode(DWORD modeFlags, bool makePublic) rBool; |
||||
|
||||
BOOL STORMAPI SNetEnumGamesEx(int a1, int a2, int (__fastcall *callback)(DWORD, DWORD, DWORD), int *hintnextcall) rBool; |
||||
BOOL STORMAPI SNetSendServerChatCommand(const char *command) rBool; |
||||
|
||||
BOOL STORMAPI SNetDisconnectAll(DWORD flags) rBool; |
||||
BOOL STORMAPI SNetCreateLadderGame(const char *pszGameName, const char *pszGamePassword, const char *pszGameStatString, DWORD dwGameType, DWORD dwGameLadderType, DWORD dwGameModeFlags, char *GameTemplateData, int GameTemplateSize, int playerCount, char *creatorName, char *a11, int *playerID) rBool; |
||||
BOOL STORMAPI SNetReportGameResult(unsigned a1, int size, int *results, const char* headerInfo, const char* detailInfo) rBool; |
||||
|
||||
int STORMAPI SNetSendLeagueCommand(char *cmd, char *callback) rInt; |
||||
int STORMAPI SNetSendReplayPath(int a1, int a2, char *replayPath) rInt; |
||||
int STORMAPI SNetGetLeagueName(int leagueID) rInt; |
||||
BOOL STORMAPI SNetGetPlayerNames(char **names) rBool; |
||||
int STORMAPI SNetLeagueLogout(char *bnetName) rInt; |
||||
int STORMAPI SNetGetLeaguePlayerName(char *curPlayerLeageName, size_t nameSize) rInt; |
||||
|
||||
HGDIOBJ STORMAPI SDlgDefDialogProc(HWND hDlg, signed int DlgType, HDC textLabel, HWND hWnd) rPVoid; |
||||
|
||||
HANDLE STORMAPI SDlgDialogBoxIndirectParam(HMODULE hModule, LPCSTR lpName, HWND hWndParent, LPVOID lpParam, LPARAM lParam) rPVoid; |
||||
|
||||
BOOL STORMAPI SDlgEndDialog(HWND hDlg, HANDLE nResult) rBool; |
||||
|
||||
BOOL STORMAPI SDlgSetControlBitmaps(HWND parentwindow, int *id, int a3, char *buffer2, char *buffer, int flags, int mask) rBool; |
||||
|
||||
BOOL STORMAPI SDlgBltToWindowE(HWND hWnd, HRGN a2, char *a3, int a4, void *buffer, RECT *rct, SIZE *size, int a8, int a9, DWORD rop) rBool; |
||||
BOOL STORMAPI SDlgSetBitmapE(HWND hWnd, int a2, char *src, int mask1, int flags, int a6, int a7, int width, int a9, int mask2) rBool; |
||||
|
||||
int STORMAPI Ordinal224(int a1) rInt; |
||||
|
||||
BOOL STORMAPI SFileCloseArchive(HANDLE hArchive) rBool; |
||||
BOOL STORMAPI SFileCloseFile(HANDLE hFile) rBool; |
||||
|
||||
BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsigned __int32 lDistanceToMove, signed __int32 volume, signed int a6, int a7) rBool; |
||||
BOOL STORMAPI SFileDdaDestroy() rBool; |
||||
BOOL STORMAPI SFileDdaEnd(HANDLE directsound) rBool; |
||||
BOOL STORMAPI SFileDdaGetPos(HANDLE directsound, int a2, int a3) rBool; |
||||
|
||||
BOOL STORMAPI SFileDdaInitialize(HANDLE directsound) rBool; |
||||
BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume) rBool; |
||||
BOOL STORMAPI SFileDestroy() rBool; |
||||
|
||||
BOOL STORMAPI SFileGetFileArchive(HANDLE hFile, HANDLE archive) rBool; |
||||
LONG STORMAPI SFileGetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) rInt; |
||||
BOOL STORMAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq) rBool; |
||||
BOOL STORMAPI SFileOpenFile(const char *filename, HANDLE *phFile) rBool; |
||||
BOOL STORMAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile) rBool; |
||||
BOOL STORMAPI SFileReadFile(HANDLE hFile, void *buffer, DWORD nNumberOfBytesToRead, DWORD *read, LONG lpDistanceToMoveHigh) rBool; |
||||
|
||||
void STORMAPI SFileSetLocale(LCID lcLocale) rVoid; |
||||
|
||||
BOOL STORMAPI SFileSetIoErrorMode(int mode, BOOL (STORMAPI *callback)(char*,int,int) ) rBool; |
||||
BOOL STORMAPI SFileGetArchiveName(HANDLE hArchive, char *name, int length) rBool; |
||||
BOOL STORMAPI SFileGetFileName(HANDLE hFile, char *buffer, int length) rBool; |
||||
|
||||
BOOL STORMAPI SFileLoadFile(char *filename, void *buffer, int buffersize, int a4, int a5) rBool; |
||||
BOOL STORMAPI SFileUnloadFile(HANDLE hFile) rBool; |
||||
BOOL STORMAPI SFileLoadFileEx(void *hArchive, char *filename, int a3, int a4, int a5, DWORD searchScope, struct _OVERLAPPED *lpOverlapped) rBool; |
||||
|
||||
BOOL STORMAPI SBltROP3(void *lpDstBuffer, void *lpSrcBuffer, int width, int height, int a5, int a6, int a7, DWORD rop) rBool; |
||||
BOOL STORMAPI SBltROP3Clipped(void *lpDstBuffer, RECT *lpDstRect, POINT *lpDstPt, int a4, void *lpSrcBuffer, RECT *lpSrcRect, POINT *lpSrcPt, int a8, int a9, DWORD rop) rBool; |
||||
|
||||
BOOL STORMAPI SBmpDecodeImage(DWORD dwImgType, void *pSrcBuffer, DWORD dwSrcBuffersize, PALETTEENTRY *pPalette, void *pDstBuffer, DWORD dwDstBuffersize, DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) rBool; |
||||
|
||||
BOOL STORMAPI SBmpLoadImage(const char *pszFileName, PALETTEENTRY *pPalette, void *pBuffer, DWORD dwBuffersize, DWORD *pdwWidth, DWORD *dwHeight, DWORD *pdwBpp) rBool; |
||||
|
||||
BOOL STORMAPI SBmpSaveImage(const char*, PALETTEENTRY*, void*, DWORD, DWORD, DWORD) rBool; |
||||
HANDLE STORMAPI SBmpAllocLoadImage(const char *fileName, PALETTEENTRY *palette, void **buffer, int *width, int *height, int unused6, int unused7, void *(STORMAPI *allocFunction)(DWORD)) rPVoid; |
||||
|
||||
BOOL STORMAPI SCodeCompile(char *directives1, char *directives2, char *loopstring, unsigned int maxiterations, unsigned int flags, HANDLE handle) rBool; |
||||
BOOL STORMAPI SCodeDelete(HANDLE handle) rBool; |
||||
|
||||
int STORMAPI SCodeExecute(HANDLE handle, int a2) rInt; |
||||
|
||||
BOOL STORMAPI SDrawAutoInitialize(HINSTANCE hInst, LPCSTR lpClassName, LPCSTR lpWindowName, WNDPROC pfnWndProc, int nMode, int nWidth, int nHeight, int nBits) rBool; |
||||
BOOL STORMAPI SDrawCaptureScreen(const char *source) rBool; |
||||
|
||||
HWND STORMAPI SDrawGetFrameWindow(HWND *sdraw_framewindow) rPVoid; |
||||
BOOL STORMAPI SDrawGetObjects(LPDIRECTDRAW *ddInterface, LPDIRECTDRAWSURFACE *primarySurface, LPDIRECTDRAWSURFACE *surface2, LPDIRECTDRAWSURFACE *surface3, LPDIRECTDRAWSURFACE *backSurface, LPDIRECTDRAWPALETTE *ddPalette, HPALETTE *hPalette) rBool; |
||||
BOOL STORMAPI SDrawGetScreenSize(DWORD *pdwWidth, DWORD *pdwHeight, DWORD *pdwBpp) rBool; |
||||
|
||||
BOOL STORMAPI SDrawLockSurface(int surfacenumber, RECT *lpDestRect, void **lplpSurface, int *lpPitch, int arg_unused) rBool; |
||||
BOOL STORMAPI SDrawManualInitialize(HWND hWnd, LPDIRECTDRAW ddInterface, LPDIRECTDRAWSURFACE primarySurface, LPDIRECTDRAWSURFACE surface2, LPDIRECTDRAWSURFACE surface3, LPDIRECTDRAWSURFACE backSurface, LPDIRECTDRAWPALETTE ddPalette, HPALETTE hPalette) rBool; |
||||
|
||||
BOOL STORMAPI SDrawPostClose() rBool; |
||||
//BOOL STORMAPI SDrawRealizePalette() rBool;
|
||||
|
||||
BOOL STORMAPI SDrawUnlockSurface(int surfacenumber, void *lpSurface, int a3, RECT *lpRect) rBool; |
||||
BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentries, PALETTEENTRY *pPalEntries, int a4) rBool; |
||||
|
||||
BOOL STORMAPI SEvtDispatch(DWORD dwMessageID, DWORD dwFlags, int type, PS_EVT pEvent) rBool; |
||||
|
||||
BOOL STORMAPI SGdiDeleteObject(HANDLE handle) rBool; |
||||
|
||||
BOOL STORMAPI SGdiExtTextOut(int a1, int a2, int a3, int a4, unsigned int a8, signed int a6, signed int a7, const char *string, unsigned int arg20) rBool; |
||||
BOOL STORMAPI SGdiImportFont(HGDIOBJ handle, int windowsfont) rBool; |
||||
|
||||
BOOL STORMAPI SGdiSelectObject(int handle) rBool; |
||||
BOOL STORMAPI SGdiSetPitch(int pitch) rBool; |
||||
|
||||
BOOL STORMAPI Ordinal393(char *string, int, int) rBool; |
||||
|
||||
void* STORMAPI SMemAlloc(size_t amount, char *logfilename, int logline, char defaultValue) rPVoid; |
||||
|
||||
BOOL STORMAPI SMemFree(void *location, char *logfilename, int logline, char defaultValue) rBool; |
||||
|
||||
void* STORMAPI SMemReAlloc(void *location, size_t amount, char *logfilename, int logline, char defaultValue) rPVoid; |
||||
|
||||
BOOL STORMAPI SRegLoadData(const char *keyname, const char *valuename, int size, LPBYTE lpData, BYTE flags, LPDWORD lpcbData) rBool; |
||||
BOOL STORMAPI SRegLoadString(const char *keyname, const char *valuename, BYTE flags, char *buffer, size_t buffersize) rBool; |
||||
BOOL STORMAPI SRegLoadValue(const char *keyname, const char *valuename, BYTE flags, int *value) rBool; |
||||
BOOL STORMAPI SRegSaveData(const char *keyname, const char *valuename, int size, BYTE *lpData, DWORD cbData) rBool; |
||||
BOOL STORMAPI SRegSaveString(const char *keyname, const char *valuename, BYTE flags, char *string) rBool; |
||||
BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE flags, DWORD result) rBool; |
||||
|
||||
BOOL STORMAPI SRegDeleteValue(const char *keyname, const char *valuename, BYTE flags) rBool; |
||||
|
||||
BOOL STORMAPI STransBlt(void *lpSurface, int x, int y, int width, HANDLE hTrans) rBool; |
||||
BOOL STORMAPI STransBltUsingMask(void *lpSurface, void *lpSource, int pitch, int width, HANDLE hTrans) rBool; |
||||
|
||||
BOOL STORMAPI STransDelete(HANDLE hTrans) rBool; |
||||
|
||||
BOOL STORMAPI STransDuplicate(HANDLE hTransSource, HANDLE hTransDest) rBool; |
||||
BOOL STORMAPI STransIntersectDirtyArray(HANDLE hTrans, char * dirtyarraymask, unsigned flags, HANDLE * phTransResult) rBool; |
||||
BOOL STORMAPI STransInvertMask(HANDLE hTrans, HANDLE * phTransResult) rBool; |
||||
|
||||
BOOL STORMAPI STransSetDirtyArrayInfo(int width, int height, int depth, int bits) rBool; |
||||
|
||||
BOOL STORMAPI STransPointInMask(HANDLE hTrans, int x, int y) rBool; |
||||
BOOL STORMAPI STransCombineMasks(HANDLE hTransA, HANDLE hTransB, int left, int top, int flags, HANDLE * phTransResult) rBool; |
||||
|
||||
BOOL STORMAPI STransCreateE(void *pBuffer, int width, int height, int bpp, int a5, int bufferSize, HANDLE *phTransOut) rBool; |
||||
|
||||
BOOL STORMAPI SVidDestroy() rBool; |
||||
BOOL STORMAPI SVidGetSize(HANDLE video, int width, int height, int zero) rBool; |
||||
BOOL STORMAPI SVidInitialize(HANDLE video) rBool; |
||||
BOOL STORMAPI SVidPlayBegin(char *filename, int arg4, int a3, int a4, int a5, int a6, HANDLE* video) rBool; |
||||
|
||||
BOOL STORMAPI SVidPlayContinueSingle(HANDLE video, int a2, int a3) rBool; |
||||
BOOL STORMAPI SVidPlayEnd(HANDLE video) rBool; |
||||
|
||||
BOOL STORMAPI SErrDisplayError(DWORD dwErrMsg, const char *logfilename, int logline, const char *message, BOOL allowOption, int exitCode) rBool; |
||||
BOOL STORMAPI SErrGetErrorStr(DWORD dwErrCode, char *buffer, size_t bufferchars) rBool; |
||||
DWORD STORMAPI SErrGetLastError() rInt; |
||||
|
||||
void STORMAPI SErrSetLastError(DWORD dwErrCode) rVoid; |
||||
|
||||
void STORMAPI SErrSuppressErrors(BOOL suppressErrors) rVoid; |
||||
|
||||
void STORMAPI SMemCopy(void *dest, const void *source, size_t size) rVoid; |
||||
void STORMAPI SMemFill(void *location, size_t length, char fillWith) rVoid; |
||||
|
||||
void STORMAPI SMemZero(void *location, DWORD length) rVoid; |
||||
int STORMAPI SMemCmp(void *location1, void *location2, DWORD size) rInt; |
||||
|
||||
int STORMAPI SStrCopy(char *dest, const char *src, int max_length) rInt; |
||||
DWORD STORMAPI SStrHash(const char *string, DWORD flags, DWORD Seed) rInt; |
||||
int STORMAPI SStrNCat(char *dest, const char *src, DWORD max_length) rInt; |
||||
|
||||
int STORMAPI SStrLen(const char* string) rInt; |
||||
|
||||
int STORMAPI SStrCmp(const char *string1, const char *string2, size_t size) rInt; |
||||
int STORMAPI SStrCmpI(const char *string1, const char *string2, size_t size) rInt; |
||||
char* STORMAPI SStrUpper(char* string) rPVoid; |
||||
|
||||
void STORMAPI SRgn523(HANDLE hRgn, RECT *pRect, int a3, int a4) rVoid; |
||||
void STORMAPI SRgnCreateRegion(HANDLE *hRgn, int a2) rVoid; |
||||
void STORMAPI SRgnDeleteRegion(HANDLE hRgn) rVoid; |
||||
|
||||
void STORMAPI SRgn529i(int handle, int a2, int a3) rVoid; |
||||
|
||||
BOOL SErrDisplayErrorFmt(DWORD dwErrMsg, const char *logfilename, int logline, BOOL allowOption, int exitCode, const char *format, ...) rBool; |
||||
|
||||
void STORMAPI SErrCatchUnhandledExceptions() rVoid; |
||||
|
||||
char* STORMAPI SStrChr(const char *string, char c) rPVoid; |
||||
char* STORMAPI SStrChrR(const char *string, char c) rPVoid; |
||||
|
||||
size_t SStrVPrintf(char *dest, size_t size, const char *format, ...) rInt; |
||||
|
||||
int STORMAPI SBigDel(void *buffer) rInt; |
||||
|
||||
int STORMAPI SBigFromBinary(void *buffer, const void *str, size_t size) rInt; |
||||
|
||||
int STORMAPI SBigNew(void **buffer) rInt; |
||||
|
||||
int STORMAPI SBigPowMod(void *buffer1, void *buffer2, int a3, int a4) rInt; |
||||
|
||||
int STORMAPI SBigToBinaryBuffer(void *buffer, int length, int a3, int a4) rInt; |
||||
//
|
||||
|
||||
void __stdcall SDrawMessageBox(char *,char *,int) rVoid; |
||||
void __cdecl SDrawDestroy(void) rVoid; |
||||
bool __cdecl StormDestroy(void) rBool; |
||||
bool __stdcall SFileSetBasePath(char *) rBool; |
||||
void __cdecl SDrawRealizePalette(void) rVoid; |
||||
bool __cdecl SVidPlayContinue(void) rBool; |
||||
bool __stdcall SNetGetOwnerTurnsWaiting(int *) rBool; |
||||
void * __stdcall SNetUnregisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)) rPVoid; |
||||
void * __stdcall SNetRegisterEventHandler(int,void (__stdcall*)(struct _SNETEVENT *)) rPVoid; |
||||
bool __stdcall SNetSetBasePlayer(int) rBool; |
||||
int __stdcall SNetInitializeProvider(unsigned long,struct _SNETPROGRAMDATA *,struct _SNETPLAYERDATA *,struct _SNETUIDATA *,struct _SNETVERSIONDATA *) rInt; |
||||
int __stdcall SNetGetProviderCaps(struct _SNETCAPS *) rInt; |
||||
int __stdcall SFileSetFilePointer(HANDLE,int,HANDLE,int) rInt; |
||||
@ -0,0 +1,441 @@
|
||||
LIBRARY "Storm" |
||||
|
||||
EXPORTS |
||||
SNetCreateGame @101 NONAME |
||||
SNetDestroy @102 NONAME |
||||
SNetEnumProviders @103 NONAME |
||||
;SNetEnumDevices @104 NONAME |
||||
SNetEnumGames @105 NONAME |
||||
SNetDropPlayer @106 NONAME |
||||
SNetGetGameInfo @107 NONAME |
||||
;SNetGetNetworkLatency @108 NONAME |
||||
SNetGetNumPlayers @109 NONAME |
||||
SNetGetOwnerTurnsWaiting @110 NONAME |
||||
;SNetGetPerformanceData @111 NONAME |
||||
SNetGetPlayerCaps @112 NONAME |
||||
SNetGetPlayerName @113 NONAME |
||||
SNetGetProviderCaps @114 NONAME |
||||
SNetGetTurnsInTransit @115 NONAME |
||||
SNetInitializeDevice @116 NONAME |
||||
SNetInitializeProvider @117 NONAME |
||||
SNetJoinGame @118 NONAME |
||||
SNetLeaveGame @119 NONAME |
||||
SNetPerformUpgrade @120 NONAME |
||||
SNetReceiveMessage @121 NONAME |
||||
SNetReceiveTurns @122 NONAME |
||||
SNetRegisterEventHandler @123 NONAME |
||||
;SNetResetLatencyMeasurements @124 NONAME |
||||
SNetSelectGame @125 NONAME |
||||
;SNetSelectProvider @126 NONAME |
||||
SNetSendMessage @127 NONAME |
||||
SNetSendTurn @128 NONAME |
||||
SNetSetBasePlayer @129 NONAME |
||||
SNetSetGameMode @130 NONAME |
||||
SNetUnregisterEventHandler @131 NONAME |
||||
|
||||
SNetEnumGamesEx @133 NONAME |
||||
SNetSendServerChatCommand @134 NONAME |
||||
;SNetSendDatagram @135 NONAME |
||||
;SNetReceiveDatagram @136 NONAME |
||||
SNetDisconnectAll @137 NONAME |
||||
SNetCreateLadderGame @138 NONAME |
||||
SNetReportGameResult @139 NONAME |
||||
;SNetCheckDataFile @140 NONAME |
||||
SNetSendLeagueCommand @141 NONAME |
||||
SNetSendReplayPath @142 NONAME |
||||
SNetGetLeagueName @143 NONAME |
||||
SNetGetPlayerNames @144 NONAME |
||||
SNetLeagueLogout @145 NONAME |
||||
SNetGetLeaguePlayerName @146 NONAME |
||||
|
||||
;Ordinal150 @150 NONAME |
||||
;Ordinal151 @151 NONAME |
||||
|
||||
;SDlgBeginPaint @201 NONAME |
||||
;SDlgBltToWindowI @202 NONAME |
||||
;SDlgCheckTimers @203 NONAME |
||||
;SDlgCreateDialogIndirectParam @204 NONAME |
||||
;SDlgCreateDialogParam @205 NONAME |
||||
SDlgDefDialogProc @206 NONAME |
||||
|
||||
SDlgDialogBoxIndirectParam @208 NONAME |
||||
;SDlgDialogBoxParam @209 NONAME |
||||
;SDlgDrawBitmap @210 NONAME |
||||
SDlgEndDialog @211 NONAME |
||||
;SDlgEndPaint @212 NONAME |
||||
;SDlgKillTimer @213 NONAME |
||||
;SDlgSetBaseFont @214 NONAME |
||||
;SDlgSetBitmapI @215 NONAME |
||||
SDlgSetControlBitmaps @216 NONAME |
||||
;SDlgSetCursor @217 NONAME |
||||
;SDlgSetSystemCursor @218 NONAME |
||||
;SDlgSetTimer @219 NONAME |
||||
;SDlgUpdateCursor @220 NONAME |
||||
SDlgBltToWindowE @221 NONAME |
||||
SDlgSetBitmapE @222 NONAME |
||||
;SDlgSetLocale @223 NONAME |
||||
Ordinal224 @224 NONAME |
||||
|
||||
;SFileAuthenticateArchive @251 NONAME |
||||
SFileCloseArchive @252 NONAME |
||||
SFileCloseFile @253 NONAME |
||||
;SFileDdaBegin @254 NONAME |
||||
SFileDdaBeginEx @255 NONAME |
||||
SFileDdaDestroy @256 NONAME |
||||
SFileDdaEnd @257 NONAME |
||||
SFileDdaGetPos @258 NONAME |
||||
;SFileDdaGetVolume @259 NONAME |
||||
SFileDdaInitialize @260 NONAME |
||||
SFileDdaSetVolume @261 NONAME |
||||
SFileDestroy @262 NONAME |
||||
;SFileEnableDirectAccess @263 NONAME |
||||
SFileGetFileArchive @264 NONAME |
||||
SFileGetFileSize @265 NONAME |
||||
SFileOpenArchive @266 NONAME |
||||
SFileOpenFile @267 NONAME |
||||
SFileOpenFileEx @268 NONAME |
||||
SFileReadFile @269 NONAME |
||||
SFileSetBasePath @270 NONAME |
||||
SFileSetFilePointer @271 NONAME |
||||
SFileSetLocale @272 NONAME |
||||
;SFileGetBasePath @273 NONAME |
||||
SFileSetIoErrorMode @274 NONAME |
||||
SFileGetArchiveName @275 NONAME |
||||
SFileGetFileName @276 NONAME |
||||
;SFileGetArchiveInfo @277 NONAME |
||||
;SFileSetPlatform @278 NONAME |
||||
SFileLoadFile @279 NONAME |
||||
SFileUnloadFile @280 NONAME |
||||
SFileLoadFileEx @281 NONAME |
||||
;SFilePrioritizeRequest @282 NONAME |
||||
;SFileCancelRequest @283 NONAME |
||||
;SFileSetAsyncBudget @284 NONAME |
||||
;SFileSetDataChunkSize @285 NONAME |
||||
;SFileEnableSeekOptimization @286 NONAME |
||||
;SFileReadFileEx @287 NONAME |
||||
;SFileFileExists @288 NONAME |
||||
;SFileFileExistsEx @289 NONAME |
||||
;SFileReadFileEx2 @290 NONAME |
||||
;SFileReadFile2 @291 NONAME |
||||
;SFileLoadFile2 @292 NONAME |
||||
;SFileOpenFileAsArchive @293 NONAME |
||||
;SFileGetLocale @294 NONAME |
||||
;SFileRegisterLoadNotifyProc @295 NONAME |
||||
;SFileGetFileCompressedSize @296 NONAME |
||||
;Ordinal297 @297 NONAME |
||||
;Ordinal298 @298 NONAME |
||||
;SFileAuthenticateArchiveEx @299 NONAME |
||||
;SFileOpenPathAsArchive @300 NONAME |
||||
StormDestroy @301 NONAME |
||||
;StormGetInstance @302 NONAME |
||||
;StormGetOption @303 NONAME |
||||
;StormSetOption @304 NONAME |
||||
|
||||
;SBltGetSCode @312 NONAME |
||||
SBltROP3 @313 NONAME |
||||
SBltROP3Clipped @314 NONAME |
||||
;SBltROP3Tiled @315 NONAME |
||||
|
||||
SBmpDecodeImage @321 NONAME |
||||
|
||||
SBmpLoadImage @323 NONAME |
||||
SBmpSaveImage @324 NONAME |
||||
SBmpAllocLoadImage @325 NONAME |
||||
;SBmpSaveImageEx @326 NONAME |
||||
|
||||
SCodeCompile @331 NONAME |
||||
SCodeDelete @332 NONAME |
||||
|
||||
SCodeExecute @334 NONAME |
||||
;SCodeGetPseudocode @335 NONAME |
||||
|
||||
SDrawAutoInitialize @341 NONAME |
||||
SDrawCaptureScreen @342 NONAME |
||||
;SDrawClearSurface @343 NONAME |
||||
SDrawDestroy @344 NONAME |
||||
;SDrawFlipPage @345 NONAME |
||||
SDrawGetFrameWindow @346 NONAME |
||||
SDrawGetObjects @347 NONAME |
||||
SDrawGetScreenSize @348 NONAME |
||||
;SDrawGetServiceLevel @349 NONAME |
||||
SDrawLockSurface @350 NONAME |
||||
SDrawManualInitialize @351 NONAME |
||||
SDrawMessageBox @352 NONAME |
||||
SDrawPostClose @353 NONAME |
||||
SDrawRealizePalette @354 NONAME |
||||
;SDrawSelectGdiSurface @355 NONAME |
||||
SDrawUnlockSurface @356 NONAME |
||||
SDrawUpdatePalette @357 NONAME |
||||
;SDrawUpdateScreen @358 NONAME |
||||
;SDrawWaitForVerticalBlank @359 NONAME |
||||
|
||||
SEvtDispatch @372 NONAME |
||||
;SEvtRegisterHandler @373 NONAME |
||||
;SEvtUnregisterHandler @374 NONAME |
||||
;SEvtUnregisterType @375 NONAME |
||||
;SEvtPopState @376 NONAME |
||||
;SEvtPushState @377 NONAME |
||||
;SEvtBreakHandlerChain @378 NONAME |
||||
|
||||
;SGdiBitBlt @381 NONAME |
||||
;SGdiCreateFont @382 NONAME |
||||
SGdiDeleteObject @383 NONAME |
||||
;SGdiDestroy @384 NONAME |
||||
SGdiExtTextOut @385 NONAME |
||||
SGdiImportFont @386 NONAME |
||||
;SGdiLoadFont @387 NONAME |
||||
;SGdiRectangle @388 NONAME |
||||
SGdiSelectObject @389 NONAME |
||||
SGdiSetPitch @390 NONAME |
||||
;SGdiTextOut @391 NONAME |
||||
;SGdi392 @392 NONAME |
||||
Ordinal393 @393 NONAME |
||||
|
||||
;SMem399 @399 NONAME |
||||
|
||||
SMemAlloc @401 NONAME |
||||
;SMemDestroy @402 NONAME |
||||
SMemFree @403 NONAME |
||||
;SMemGetSize @404 NONAME |
||||
SMemReAlloc @405 NONAME |
||||
;Storm406 @406 NONAME |
||||
|
||||
;SMsgDispatchMessage @412 NONAME |
||||
;SMsgDoMessageLoop @413 NONAME |
||||
;SMsgRegisterCommand @414 NONAME |
||||
;SMsgRegisterKeyDown @415 NONAME |
||||
;SMsgRegisterKeyUp @416 NONAME |
||||
;SMsgRegisterMessage @417 NONAME |
||||
;SMsgPopRegisterState @418 NONAME |
||||
;SMsgPushRegisterState @419 NONAME |
||||
;SMsg420 @420 NONAME |
||||
SRegLoadData @421 NONAME |
||||
SRegLoadString @422 NONAME |
||||
SRegLoadValue @423 NONAME |
||||
SRegSaveData @424 NONAME |
||||
SRegSaveString @425 NONAME |
||||
SRegSaveValue @426 NONAME |
||||
;SRegGetBaseKey @427 NONAME |
||||
SRegDeleteValue @428 NONAME |
||||
;SReg429 @429 NONAME |
||||
;SReg430 @430 NONAME |
||||
STransBlt @431 NONAME |
||||
STransBltUsingMask @432 NONAME |
||||
;STransCreateI @433 NONAME |
||||
STransDelete @434 NONAME |
||||
|
||||
STransDuplicate @436 NONAME |
||||
STransIntersectDirtyArray @437 NONAME |
||||
STransInvertMask @438 NONAME |
||||
;STransLoadI @439 NONAME |
||||
STransSetDirtyArrayInfo @440 NONAME |
||||
;STransUpdateDirtyArray @441 NONAME |
||||
STransPointInMask @442 NONAME |
||||
STransCombineMasks @443 NONAME |
||||
;STransCreateI @444 NONAME |
||||
STransCreateE @445 NONAME |
||||
;STrans446 @446 NONAME |
||||
;STransLoadE @447 NONAME |
||||
|
||||
SVidDestroy @451 NONAME |
||||
SVidGetSize @452 NONAME |
||||
SVidInitialize @453 NONAME |
||||
SVidPlayBegin @454 NONAME |
||||
;SVidPlayBeginFromMemory @455 NONAME |
||||
SVidPlayContinue @456 NONAME |
||||
SVidPlayContinueSingle @457 NONAME |
||||
SVidPlayEnd @458 NONAME |
||||
;SVidSetVolume @459 NONAME |
||||
;Storm460 @460 NONAME |
||||
SErrDisplayError @461 NONAME |
||||
SErrGetErrorStr @462 NONAME |
||||
SErrGetLastError @463 NONAME |
||||
;SErrRegisterMessageSource @464 NONAME |
||||
SErrSetLastError @465 NONAME |
||||
;SErrReportNamedResourceLeak @466 NONAME |
||||
;SErrReportResourceLeak @467 NONAME |
||||
SErrSuppressErrors @468 NONAME |
||||
;SErrRegisterHandler @469 NONAME |
||||
;SErrUnregisterHandler @470 NONAME |
||||
;Storm471 @471 NONAME |
||||
;SCmdGetBool @472 NONAME |
||||
;SCmdGetNum @473 NONAME |
||||
;SCmdGetString @474 NONAME |
||||
;SCmdProcess @475 NONAME |
||||
;SCmdRegisterArgList @476 NONAME |
||||
;SCmdRegisterArgument @477 NONAME |
||||
;SCmdStringExists @478 NONAME |
||||
;SCmdProcessCommandLine @479 NONAME |
||||
;Ordinal480 @480 NONAME |
||||
;SMemFindNextBlock @481 NONAME |
||||
;SMemFindNextHeap @482 NONAME |
||||
;SMemGetHeapByCaller @483 NONAME |
||||
;SMemGetHeapByPtr @484 NONAME |
||||
;SMemHeapAlloc @485 NONAME |
||||
;SMemHeapCreate @486 NONAME |
||||
;SMemHeapDestroy @487 NONAME |
||||
;SMemHeapFree @488 NONAME |
||||
;SMemHeapRealloc @489 NONAME |
||||
;SMemHeapSize @490 NONAME |
||||
SMemCopy @491 NONAME |
||||
SMemFill @492 NONAME |
||||
;SMemMove @493 NONAME |
||||
SMemZero @494 NONAME |
||||
SMemCmp @495 NONAME |
||||
;SMem496 @496 NONAME |
||||
;SMemDumpState @497 NONAME |
||||
;Ordinal498 @498 NONAME |
||||
|
||||
SStrCopy @501 NONAME |
||||
SStrHash @502 NONAME |
||||
SStrNCat @503 NONAME |
||||
;SStrTokenize @504 NONAME |
||||
;SStrPack @505 NONAME |
||||
SStrLen @506 NONAME |
||||
;SStrDup @507 NONAME |
||||
SStrCmp @508 NONAME |
||||
SStrCmpI @509 NONAME |
||||
SStrUpper @510 NONAME |
||||
;SMsgBreakHandlerChain @511 NONAME |
||||
;SMsgUnregisterCommand @512 NONAME |
||||
;SMsgUnregisterKeyDown @513 NONAME |
||||
;SMsgUnregisterKeyUp @514 NONAME |
||||
;SMsgUnregisterMessage @515 NONAME |
||||
;SMsgGetDispatcher @516 NONAME |
||||
;SMsgSetDefaultWindow @517 NONAME |
||||
;SMsgGetDefaultWindow @518 NONAME |
||||
;SMsg519 @519 NONAME |
||||
|
||||
;SRgn521 @521 NONAME |
||||
|
||||
SRgn523 @523 NONAME |
||||
SRgnCreateRegion @524 NONAME |
||||
SRgnDeleteRegion @525 NONAME |
||||
|
||||
;SRgn527 @527 NONAME |
||||
;SRgn528i @528 NONAME |
||||
SRgn529i @529 NONAME |
||||
;SRgn530i @530 NONAME |
||||
;SRgn531i @531 NONAME |
||||
;SRgn532i @532 NONAME |
||||
;SRgn533i @533 NONAME |
||||
;SRgn534 @534 NONAME |
||||
;SRgn535f @535 NONAME |
||||
;SRgn536f @536 NONAME |
||||
;SRgn537f @537 NONAME |
||||
;SRgn538f @538 NONAME |
||||
;SRgn539f @539 NONAME |
||||
;SRgn540f @540 NONAME |
||||
;SLogClose @541 NONAME |
||||
;SLogCreate @542 NONAME |
||||
;SLog543 @543 NONAME |
||||
;SLogDump @544 NONAME |
||||
;SLogFlush @545 NONAME |
||||
;SLogFlushAll @546 NONAME |
||||
;SLogPend @547 NONAME |
||||
;SLogWrite @548 NONAME |
||||
;SLog549 @549 NONAME |
||||
;SLogCriticalLog @550 NONAME |
||||
;SCompCompress @551 NONAME |
||||
;SCompDecompress @552 NONAME |
||||
;SLogVWrite @553 NONAME |
||||
;Ordinal554 @554 NONAME |
||||
;Ordinal555 @555 NONAME |
||||
;Ordinal556 @556 NONAME |
||||
;Ordinal557 @557 NONAME |
||||
;Ordinal558 @558 NONAME |
||||
;Ordinal559 @559 NONAME |
||||
;Ordinal560 @560 NONAME |
||||
;SErrCheckDebugSymbolLibrary @561 NONAME |
||||
SErrDisplayErrorFmt @562 NONAME |
||||
;SErrIsDisplayingError @563 NONAME |
||||
;SErrPrepareAppFatal @564 NONAME |
||||
;SErrSetLogTitleString @565 NONAME |
||||
;SErrDisplayAppFatal @566 NONAME |
||||
SErrCatchUnhandledExceptions @567 NONAME |
||||
;Storm568 @568 NONAME |
||||
;SStrChr @569 NONAME |
||||
;SStrChrR @570 NONAME |
||||
SStrChr @571 NONAME |
||||
SStrChrR @572 NONAME |
||||
;SStrToDouble @573 NONAME |
||||
;SStrToFloat @574 NONAME |
||||
;SStrToInt @575 NONAME |
||||
;SStrToUnsigned @576 NONAME |
||||
;SStrToInt64 @577 NONAME |
||||
SStrVPrintf @578 NONAME |
||||
;SStrLower @579 NONAME |
||||
;SStrHash64 @580 NONAME |
||||
;SStrPrintf @581 NONAME |
||||
;SDrawSetClientRect @582 NONAME |
||||
;SDrawGetClientRect @583 NONAME |
||||
;SStrStrI @584 NONAME |
||||
;SStrStrI @585 NONAME |
||||
;SStrStr @586 NONAME |
||||
;SStrStr @587 NONAME |
||||
;SNet588 @588 NONAME |
||||
|
||||
;SBigAdd @601 NONAME |
||||
;SBigAnd @602 NONAME |
||||
;SBigCompare @603 NONAME |
||||
;SBigCopy @604 NONAME |
||||
;SBigDec @605 NONAME |
||||
SBigDel @606 NONAME |
||||
;SBigDiv @607 NONAME |
||||
;SBigFindPrime @608 NONAME |
||||
SBigFromBinary @609 NONAME |
||||
;SBigFromStr @610 NONAME |
||||
;SBigFromStream @611 NONAME |
||||
;SBigFromUnsigned @612 NONAME |
||||
;SBigGcd @613 NONAME |
||||
;SBigInc @614 NONAME |
||||
;SBigInvMod @615 NONAME |
||||
;SBigIsEven @616 NONAME |
||||
;SBigIsOdd @617 NONAME |
||||
;SBigIsOne @618 NONAME |
||||
;SBigIsPrime @619 NONAME |
||||
;SBigIsZero @620 NONAME |
||||
;SBigMod @621 NONAME |
||||
;SBigMul @622 NONAME |
||||
;SBigMulMod @623 NONAME |
||||
SBigNew @624 NONAME |
||||
;SBigNot @625 NONAME |
||||
;SBigOr @626 NONAME |
||||
;SBigPow @627 NONAME |
||||
SBigPowMod @628 NONAME |
||||
;SBigRand @629 NONAME |
||||
;SBigSet2Exp @630 NONAME |
||||
;SBigSetOne @631 NONAME |
||||
;SBigSetZero @632 NONAME |
||||
;SBigShl @633 NONAME |
||||
;SBigShr @634 NONAME |
||||
;SBigSquare @635 NONAME |
||||
;SBigSub @636 NONAME |
||||
;SBigToBinaryArray @637 NONAME |
||||
SBigToBinaryBuffer @638 NONAME |
||||
;SBigToBinaryPtr @639 NONAME |
||||
;SBigToStrArray @640 NONAME |
||||
;SBigToStrBuffer @641 NONAME |
||||
;SBigToStrPtr @642 NONAME |
||||
;SBigToStreamArray @643 NONAME |
||||
;SBigToStreamBuffer @644 NONAME |
||||
;SBigToStreamPtr @645 NONAME |
||||
;SBigToUnsigned @646 NONAME |
||||
;SBigXor @647 NONAME |
||||
|
||||
;SUniConvertUTF16to8Len @901 NONAME |
||||
;SUniConvertUTF16to8 @902 NONAME |
||||
;SUniConvertUTF8to16Len @903 NONAME |
||||
;SUniConvertUTF8to16 @904 NONAME |
||||
;SUniS905 @905 NONAME |
||||
;SUniS906 @906 NONAME |
||||
;SUniFindAfterUTF8Chr @907 NONAME |
||||
;SUniFindUTF8ChrStart @908 NONAME |
||||
;SUniConvertUTF16To909 @909 NONAME |
||||
;SUniConvertUTF16To910 @910 NONAME |
||||
;SUniConvertUTF16To911 @911 NONAME |
||||
;SUniConvert912 @912 NONAME |
||||
;SUniConvert913 @913 NONAME |
||||
;SUniConvert914 @914 NONAME |
||||
;SUniConvertUTF8ToWin @915 NONAME |
||||
; END |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,495 @@
|
||||
LIBRARY "Storm" |
||||
|
||||
EXPORTS |
||||
SNetCreateGame @101 NONAME |
||||
SNetCreateGame@40 @101 NONAME |
||||
SNetDestroy @102 NONAME |
||||
SNetDestroy@0 @102 NONAME |
||||
SNetEnumProviders @103 NONAME |
||||
;SNetEnumDevices @104 NONAME |
||||
SNetEnumGames @105 NONAME |
||||
SNetDropPlayer @106 NONAME |
||||
SNetDropPlayer@8 @106 NONAME |
||||
SNetGetGameInfo @107 NONAME |
||||
SNetGetGameInfo@16 @107 NONAME |
||||
;SNetGetNetworkLatency @108 NONAME |
||||
SNetGetNumPlayers @109 NONAME |
||||
SNetGetOwnerTurnsWaiting @110 NONAME |
||||
SNetGetOwnerTurnsWaiting@4 @110 NONAME |
||||
;SNetGetPerformanceData @111 NONAME |
||||
SNetGetPlayerCaps @112 NONAME |
||||
SNetGetPlayerName @113 NONAME |
||||
SNetGetProviderCaps @114 NONAME |
||||
SNetGetProviderCaps@4 @114 NONAME |
||||
SNetGetTurnsInTransit @115 NONAME |
||||
SNetGetTurnsInTransit@4 @115 NONAME |
||||
SNetInitializeDevice @116 NONAME |
||||
SNetInitializeProvider @117 NONAME |
||||
SNetInitializeProvider@20 @117 NONAME |
||||
SNetJoinGame @118 NONAME |
||||
SNetLeaveGame @119 NONAME |
||||
SNetLeaveGame@4 @119 NONAME |
||||
SNetPerformUpgrade @120 NONAME |
||||
SNetPerformUpgrade@4 @120 NONAME |
||||
SNetReceiveMessage @121 NONAME |
||||
SNetReceiveMessage@12 @121 NONAME |
||||
SNetReceiveTurns @122 NONAME |
||||
SNetReceiveTurns@20 @122 NONAME |
||||
SNetRegisterEventHandler @123 NONAME |
||||
SNetRegisterEventHandler@8 @123 NONAME |
||||
;SNetResetLatencyMeasurements @124 NONAME |
||||
SNetSelectGame @125 NONAME |
||||
;SNetSelectProvider @126 NONAME |
||||
SNetSendMessage @127 NONAME |
||||
SNetSendMessage@12 @127 NONAME |
||||
SNetSendTurn @128 NONAME |
||||
SNetSendTurn@8 @128 NONAME |
||||
SNetSetBasePlayer @129 NONAME |
||||
SNetSetBasePlayer@4 @129 NONAME |
||||
SNetSetGameMode @130 NONAME |
||||
SNetUnregisterEventHandler @131 NONAME |
||||
SNetUnregisterEventHandler@8 @131 NONAME |
||||
|
||||
SNetEnumGamesEx @133 NONAME |
||||
SNetSendServerChatCommand @134 NONAME |
||||
SNetSendServerChatCommand@4 @134 NONAME |
||||
;SNetSendDatagram @135 NONAME |
||||
;SNetReceiveDatagram @136 NONAME |
||||
SNetDisconnectAll @137 NONAME |
||||
SNetCreateLadderGame @138 NONAME |
||||
SNetReportGameResult @139 NONAME |
||||
;SNetCheckDataFile @140 NONAME |
||||
SNetSendLeagueCommand @141 NONAME |
||||
SNetSendReplayPath @142 NONAME |
||||
SNetGetLeagueName @143 NONAME |
||||
SNetGetPlayerNames @144 NONAME |
||||
SNetLeagueLogout @145 NONAME |
||||
SNetGetLeaguePlayerName @146 NONAME |
||||
|
||||
;Ordinal150 @150 NONAME |
||||
;Ordinal151 @151 NONAME |
||||
|
||||
;SDlgBeginPaint @201 NONAME |
||||
;SDlgBltToWindowI @202 NONAME |
||||
;SDlgCheckTimers @203 NONAME |
||||
;SDlgCreateDialogIndirectParam @204 NONAME |
||||
;SDlgCreateDialogParam @205 NONAME |
||||
SDlgDefDialogProc @206 NONAME |
||||
|
||||
SDlgDialogBoxIndirectParam @208 NONAME |
||||
;SDlgDialogBoxParam @209 NONAME |
||||
;SDlgDrawBitmap @210 NONAME |
||||
SDlgEndDialog @211 NONAME |
||||
;SDlgEndPaint @212 NONAME |
||||
;SDlgKillTimer @213 NONAME |
||||
;SDlgSetBaseFont @214 NONAME |
||||
;SDlgSetBitmapI @215 NONAME |
||||
SDlgSetControlBitmaps @216 NONAME |
||||
;SDlgSetCursor @217 NONAME |
||||
;SDlgSetSystemCursor @218 NONAME |
||||
;SDlgSetTimer @219 NONAME |
||||
;SDlgUpdateCursor @220 NONAME |
||||
SDlgBltToWindowE @221 NONAME |
||||
SDlgSetBitmapE @222 NONAME |
||||
;SDlgSetLocale @223 NONAME |
||||
Ordinal224 @224 NONAME |
||||
|
||||
;SFileAuthenticateArchive @251 NONAME |
||||
SFileCloseArchive @252 NONAME |
||||
SFileCloseArchive@4 @252 NONAME |
||||
SFileCloseFile @253 NONAME |
||||
SFileCloseFile@4 @253 NONAME |
||||
;SFileDdaBegin @254 NONAME |
||||
SFileDdaBeginEx @255 NONAME |
||||
SFileDdaBeginEx@28 @255 NONAME |
||||
SFileDdaDestroy @256 NONAME |
||||
SFileDdaDestroy@0 @256 NONAME |
||||
SFileDdaEnd @257 NONAME |
||||
SFileDdaEnd@4 @257 NONAME |
||||
SFileDdaGetPos @258 NONAME |
||||
SFileDdaGetPos@12 @258 NONAME |
||||
;SFileDdaGetVolume @259 NONAME |
||||
SFileDdaInitialize @260 NONAME |
||||
SFileDdaInitialize@4 @260 NONAME |
||||
SFileDdaSetVolume @261 NONAME |
||||
SFileDdaSetVolume@12 @261 NONAME |
||||
SFileDestroy @262 NONAME |
||||
;SFileEnableDirectAccess @263 NONAME |
||||
SFileGetFileArchive @264 NONAME |
||||
SFileGetFileArchive@8 @264 NONAME |
||||
SFileGetFileSize @265 NONAME |
||||
SFileGetFileSize@8 @265 NONAME |
||||
SFileOpenArchive @266 NONAME |
||||
SFileOpenArchive@16 @266 NONAME |
||||
SFileOpenFile @267 NONAME |
||||
SFileOpenFile@8 @267 NONAME |
||||
SFileOpenFileEx @268 NONAME |
||||
SFileOpenFileEx@16 @268 NONAME |
||||
SFileReadFile @269 NONAME |
||||
SFileReadFile@20 @269 NONAME |
||||
SFileSetBasePath @270 NONAME |
||||
SFileSetBasePath@4 @270 NONAME |
||||
SFileSetFilePointer @271 NONAME |
||||
SFileSetFilePointer@16 @271 NONAME |
||||
SFileSetLocale @272 NONAME |
||||
;SFileGetBasePath @273 NONAME |
||||
SFileSetIoErrorMode @274 NONAME |
||||
SFileGetArchiveName @275 NONAME |
||||
SFileGetFileName @276 NONAME |
||||
;SFileGetArchiveInfo @277 NONAME |
||||
;SFileSetPlatform @278 NONAME |
||||
SFileLoadFile @279 NONAME |
||||
SFileUnloadFile @280 NONAME |
||||
SFileLoadFileEx @281 NONAME |
||||
;SFilePrioritizeRequest @282 NONAME |
||||
;SFileCancelRequest @283 NONAME |
||||
;SFileSetAsyncBudget @284 NONAME |
||||
;SFileSetDataChunkSize @285 NONAME |
||||
;SFileEnableSeekOptimization @286 NONAME |
||||
;SFileReadFileEx @287 NONAME |
||||
;SFileFileExists @288 NONAME |
||||
;SFileFileExistsEx @289 NONAME |
||||
;SFileReadFileEx2 @290 NONAME |
||||
;SFileReadFile2 @291 NONAME |
||||
;SFileLoadFile2 @292 NONAME |
||||
;SFileOpenFileAsArchive @293 NONAME |
||||
;SFileGetLocale @294 NONAME |
||||
;SFileRegisterLoadNotifyProc @295 NONAME |
||||
;SFileGetFileCompressedSize @296 NONAME |
||||
;Ordinal297 @297 NONAME |
||||
;Ordinal298 @298 NONAME |
||||
;SFileAuthenticateArchiveEx @299 NONAME |
||||
;SFileOpenPathAsArchive @300 NONAME |
||||
StormDestroy @301 NONAME |
||||
;StormGetInstance @302 NONAME |
||||
;StormGetOption @303 NONAME |
||||
;StormSetOption @304 NONAME |
||||
|
||||
;SBltGetSCode @312 NONAME |
||||
SBltROP3 @313 NONAME |
||||
SBltROP3Clipped @314 NONAME |
||||
;SBltROP3Tiled @315 NONAME |
||||
|
||||
SBmpDecodeImage @321 NONAME |
||||
|
||||
SBmpLoadImage @323 NONAME |
||||
SBmpSaveImage @324 NONAME |
||||
SBmpAllocLoadImage @325 NONAME |
||||
;SBmpSaveImageEx @326 NONAME |
||||
|
||||
SCodeCompile @331 NONAME |
||||
SCodeDelete @332 NONAME |
||||
|
||||
SCodeExecute @334 NONAME |
||||
;SCodeGetPseudocode @335 NONAME |
||||
|
||||
SDrawAutoInitialize @341 NONAME |
||||
SDrawCaptureScreen @342 NONAME |
||||
;SDrawClearSurface @343 NONAME |
||||
SDrawDestroy @344 NONAME |
||||
;SDrawFlipPage @345 NONAME |
||||
SDrawGetFrameWindow @346 NONAME |
||||
SDrawGetFrameWindow@4 @346 NONAME |
||||
SDrawGetObjects @347 NONAME |
||||
SDrawGetScreenSize @348 NONAME |
||||
;SDrawGetServiceLevel @349 NONAME |
||||
SDrawLockSurface @350 NONAME |
||||
SDrawManualInitialize @351 NONAME |
||||
SDrawManualInitialize@32 @351 NONAME |
||||
SDrawMessageBox @352 NONAME |
||||
SDrawMessageBox@12 @352 NONAME |
||||
SDrawPostClose @353 NONAME |
||||
SDrawRealizePalette @354 NONAME |
||||
;SDrawSelectGdiSurface @355 NONAME |
||||
SDrawUnlockSurface @356 NONAME |
||||
SDrawUpdatePalette @357 NONAME |
||||
SDrawUpdatePalette@16 @357 NONAME |
||||
;SDrawUpdateScreen @358 NONAME |
||||
;SDrawWaitForVerticalBlank @359 NONAME |
||||
|
||||
SEvtDispatch @372 NONAME |
||||
;SEvtRegisterHandler @373 NONAME |
||||
;SEvtUnregisterHandler @374 NONAME |
||||
;SEvtUnregisterType @375 NONAME |
||||
;SEvtPopState @376 NONAME |
||||
;SEvtPushState @377 NONAME |
||||
;SEvtBreakHandlerChain @378 NONAME |
||||
|
||||
;SGdiBitBlt @381 NONAME |
||||
;SGdiCreateFont @382 NONAME |
||||
SGdiDeleteObject @383 NONAME |
||||
;SGdiDestroy @384 NONAME |
||||
SGdiExtTextOut @385 NONAME |
||||
SGdiImportFont @386 NONAME |
||||
;SGdiLoadFont @387 NONAME |
||||
;SGdiRectangle @388 NONAME |
||||
SGdiSelectObject @389 NONAME |
||||
SGdiSetPitch @390 NONAME |
||||
;SGdiTextOut @391 NONAME |
||||
;SGdi392 @392 NONAME |
||||
Ordinal393 @393 NONAME |
||||
|
||||
;SMem399 @399 NONAME |
||||
|
||||
SMemAlloc @401 NONAME |
||||
SMemAlloc@16 @401 NONAME |
||||
;SMemDestroy @402 NONAME |
||||
SMemFree @403 NONAME |
||||
SMemFree@16 @403 NONAME |
||||
;SMemGetSize @404 NONAME |
||||
SMemReAlloc @405 NONAME |
||||
;Storm406 @406 NONAME |
||||
|
||||
;SMsgDispatchMessage @412 NONAME |
||||
;SMsgDoMessageLoop @413 NONAME |
||||
;SMsgRegisterCommand @414 NONAME |
||||
;SMsgRegisterKeyDown @415 NONAME |
||||
;SMsgRegisterKeyUp @416 NONAME |
||||
;SMsgRegisterMessage @417 NONAME |
||||
;SMsgPopRegisterState @418 NONAME |
||||
;SMsgPushRegisterState @419 NONAME |
||||
;SMsg420 @420 NONAME |
||||
SRegLoadData @421 NONAME |
||||
SRegLoadData@24 @421 NONAME |
||||
SRegLoadString @422 NONAME |
||||
SRegLoadString@20 @422 NONAME |
||||
SRegLoadValue @423 NONAME |
||||
SRegLoadValue@16 @423 NONAME |
||||
SRegSaveData @424 NONAME |
||||
SRegSaveData@20 @424 NONAME |
||||
SRegSaveString @425 NONAME |
||||
SRegSaveString@16 @425 NONAME |
||||
SRegSaveValue @426 NONAME |
||||
SRegSaveValue@16 @426 NONAME |
||||
;SRegGetBaseKey @427 NONAME |
||||
SRegDeleteValue @428 NONAME |
||||
;SReg429 @429 NONAME |
||||
;SReg430 @430 NONAME |
||||
STransBlt @431 NONAME |
||||
STransBltUsingMask @432 NONAME |
||||
;STransCreateI @433 NONAME |
||||
STransDelete @434 NONAME |
||||
|
||||
STransDuplicate @436 NONAME |
||||
STransIntersectDirtyArray @437 NONAME |
||||
STransInvertMask @438 NONAME |
||||
;STransLoadI @439 NONAME |
||||
STransSetDirtyArrayInfo @440 NONAME |
||||
;STransUpdateDirtyArray @441 NONAME |
||||
STransPointInMask @442 NONAME |
||||
STransCombineMasks @443 NONAME |
||||
;STransCreateI @444 NONAME |
||||
STransCreateE @445 NONAME |
||||
;STrans446 @446 NONAME |
||||
;STransLoadE @447 NONAME |
||||
|
||||
SVidDestroy @451 NONAME |
||||
SVidDestroy@0 @451 NONAME |
||||
SVidGetSize @452 NONAME |
||||
SVidInitialize @453 NONAME |
||||
SVidInitialize@4 @453 NONAME |
||||
SVidPlayBegin @454 NONAME |
||||
SVidPlayBegin@28 @454 NONAME |
||||
;SVidPlayBeginFromMemory @455 NONAME |
||||
SVidPlayContinue @456 NONAME |
||||
SVidPlayContinueSingle @457 NONAME |
||||
SVidPlayEnd @458 NONAME |
||||
SVidPlayEnd@4 @458 NONAME |
||||
;SVidSetVolume @459 NONAME |
||||
;Storm460 @460 NONAME |
||||
SErrDisplayError @461 NONAME |
||||
SErrGetErrorStr @462 NONAME |
||||
SErrGetErrorStr@12 @462 NONAME |
||||
SErrGetLastError @463 NONAME |
||||
SErrGetLastError@0 @463 NONAME |
||||
;SErrRegisterMessageSource @464 NONAME |
||||
SErrSetLastError @465 NONAME |
||||
SErrSetLastError@4 @465 NONAME |
||||
;SErrReportNamedResourceLeak @466 NONAME |
||||
;SErrReportResourceLeak @467 NONAME |
||||
SErrSuppressErrors @468 NONAME |
||||
;SErrRegisterHandler @469 NONAME |
||||
;SErrUnregisterHandler @470 NONAME |
||||
;Storm471 @471 NONAME |
||||
;SCmdGetBool @472 NONAME |
||||
;SCmdGetNum @473 NONAME |
||||
;SCmdGetString @474 NONAME |
||||
;SCmdProcess @475 NONAME |
||||
;SCmdRegisterArgList @476 NONAME |
||||
;SCmdRegisterArgument @477 NONAME |
||||
;SCmdStringExists @478 NONAME |
||||
;SCmdProcessCommandLine @479 NONAME |
||||
;Ordinal480 @480 NONAME |
||||
;SMemFindNextBlock @481 NONAME |
||||
;SMemFindNextHeap @482 NONAME |
||||
;SMemGetHeapByCaller @483 NONAME |
||||
;SMemGetHeapByPtr @484 NONAME |
||||
;SMemHeapAlloc @485 NONAME |
||||
;SMemHeapCreate @486 NONAME |
||||
;SMemHeapDestroy @487 NONAME |
||||
;SMemHeapFree @488 NONAME |
||||
;SMemHeapRealloc @489 NONAME |
||||
;SMemHeapSize @490 NONAME |
||||
SMemCopy @491 NONAME |
||||
SMemFill @492 NONAME |
||||
;SMemMove @493 NONAME |
||||
SMemZero @494 NONAME |
||||
SMemCmp @495 NONAME |
||||
;SMem496 @496 NONAME |
||||
;SMemDumpState @497 NONAME |
||||
;Ordinal498 @498 NONAME |
||||
|
||||
SStrCopy @501 NONAME |
||||
SStrCopy@12 @501 NONAME |
||||
SStrHash @502 NONAME |
||||
SStrNCat @503 NONAME |
||||
;SStrTokenize @504 NONAME |
||||
;SStrPack @505 NONAME |
||||
SStrLen @506 NONAME |
||||
;SStrDup @507 NONAME |
||||
SStrCmp @508 NONAME |
||||
SStrCmpI @509 NONAME |
||||
SStrUpper @510 NONAME |
||||
;SMsgBreakHandlerChain @511 NONAME |
||||
;SMsgUnregisterCommand @512 NONAME |
||||
;SMsgUnregisterKeyDown @513 NONAME |
||||
;SMsgUnregisterKeyUp @514 NONAME |
||||
;SMsgUnregisterMessage @515 NONAME |
||||
;SMsgGetDispatcher @516 NONAME |
||||
;SMsgSetDefaultWindow @517 NONAME |
||||
;SMsgGetDefaultWindow @518 NONAME |
||||
;SMsg519 @519 NONAME |
||||
|
||||
;SRgn521 @521 NONAME |
||||
|
||||
SRgn523 @523 NONAME |
||||
SRgnCreateRegion @524 NONAME |
||||
SRgnDeleteRegion @525 NONAME |
||||
|
||||
;SRgn527 @527 NONAME |
||||
;SRgn528i @528 NONAME |
||||
SRgn529i @529 NONAME |
||||
;SRgn530i @530 NONAME |
||||
;SRgn531i @531 NONAME |
||||
;SRgn532i @532 NONAME |
||||
;SRgn533i @533 NONAME |
||||
;SRgn534 @534 NONAME |
||||
;SRgn535f @535 NONAME |
||||
;SRgn536f @536 NONAME |
||||
;SRgn537f @537 NONAME |
||||
;SRgn538f @538 NONAME |
||||
;SRgn539f @539 NONAME |
||||
;SRgn540f @540 NONAME |
||||
;SLogClose @541 NONAME |
||||
;SLogCreate @542 NONAME |
||||
;SLog543 @543 NONAME |
||||
;SLogDump @544 NONAME |
||||
;SLogFlush @545 NONAME |
||||
;SLogFlushAll @546 NONAME |
||||
;SLogPend @547 NONAME |
||||
;SLogWrite @548 NONAME |
||||
;SLog549 @549 NONAME |
||||
;SLogCriticalLog @550 NONAME |
||||
;SCompCompress @551 NONAME |
||||
;SCompDecompress @552 NONAME |
||||
;SLogVWrite @553 NONAME |
||||
;Ordinal554 @554 NONAME |
||||
;Ordinal555 @555 NONAME |
||||
;Ordinal556 @556 NONAME |
||||
;Ordinal557 @557 NONAME |
||||
;Ordinal558 @558 NONAME |
||||
;Ordinal559 @559 NONAME |
||||
;Ordinal560 @560 NONAME |
||||
;SErrCheckDebugSymbolLibrary @561 NONAME |
||||
SErrDisplayErrorFmt @562 NONAME |
||||
;SErrIsDisplayingError @563 NONAME |
||||
;SErrPrepareAppFatal @564 NONAME |
||||
;SErrSetLogTitleString @565 NONAME |
||||
;SErrDisplayAppFatal @566 NONAME |
||||
SErrCatchUnhandledExceptions @567 NONAME |
||||
;Storm568 @568 NONAME |
||||
;SStrChr @569 NONAME |
||||
;SStrChrR @570 NONAME |
||||
SStrChr @571 NONAME |
||||
SStrChrR @572 NONAME |
||||
;SStrToDouble @573 NONAME |
||||
;SStrToFloat @574 NONAME |
||||
;SStrToInt @575 NONAME |
||||
;SStrToUnsigned @576 NONAME |
||||
;SStrToInt64 @577 NONAME |
||||
SStrVPrintf @578 NONAME |
||||
;SStrLower @579 NONAME |
||||
;SStrHash64 @580 NONAME |
||||
;SStrPrintf @581 NONAME |
||||
;SDrawSetClientRect @582 NONAME |
||||
;SDrawGetClientRect @583 NONAME |
||||
;SStrStrI @584 NONAME |
||||
;SStrStrI @585 NONAME |
||||
;SStrStr @586 NONAME |
||||
;SStrStr @587 NONAME |
||||
;SNet588 @588 NONAME |
||||
|
||||
;SBigAdd @601 NONAME |
||||
;SBigAnd @602 NONAME |
||||
;SBigCompare @603 NONAME |
||||
;SBigCopy @604 NONAME |
||||
;SBigDec @605 NONAME |
||||
SBigDel @606 NONAME |
||||
;SBigDiv @607 NONAME |
||||
;SBigFindPrime @608 NONAME |
||||
SBigFromBinary @609 NONAME |
||||
;SBigFromStr @610 NONAME |
||||
;SBigFromStream @611 NONAME |
||||
;SBigFromUnsigned @612 NONAME |
||||
;SBigGcd @613 NONAME |
||||
;SBigInc @614 NONAME |
||||
;SBigInvMod @615 NONAME |
||||
;SBigIsEven @616 NONAME |
||||
;SBigIsOdd @617 NONAME |
||||
;SBigIsOne @618 NONAME |
||||
;SBigIsPrime @619 NONAME |
||||
;SBigIsZero @620 NONAME |
||||
;SBigMod @621 NONAME |
||||
;SBigMul @622 NONAME |
||||
;SBigMulMod @623 NONAME |
||||
SBigNew @624 NONAME |
||||
;SBigNot @625 NONAME |
||||
;SBigOr @626 NONAME |
||||
;SBigPow @627 NONAME |
||||
SBigPowMod @628 NONAME |
||||
;SBigRand @629 NONAME |
||||
;SBigSet2Exp @630 NONAME |
||||
;SBigSetOne @631 NONAME |
||||
;SBigSetZero @632 NONAME |
||||
;SBigShl @633 NONAME |
||||
;SBigShr @634 NONAME |
||||
;SBigSquare @635 NONAME |
||||
;SBigSub @636 NONAME |
||||
;SBigToBinaryArray @637 NONAME |
||||
SBigToBinaryBuffer @638 NONAME |
||||
;SBigToBinaryPtr @639 NONAME |
||||
;SBigToStrArray @640 NONAME |
||||
;SBigToStrBuffer @641 NONAME |
||||
;SBigToStrPtr @642 NONAME |
||||
;SBigToStreamArray @643 NONAME |
||||
;SBigToStreamBuffer @644 NONAME |
||||
;SBigToStreamPtr @645 NONAME |
||||
;SBigToUnsigned @646 NONAME |
||||
;SBigXor @647 NONAME |
||||
|
||||
;SUniConvertUTF16to8Len @901 NONAME |
||||
;SUniConvertUTF16to8 @902 NONAME |
||||
;SUniConvertUTF8to16Len @903 NONAME |
||||
;SUniConvertUTF8to16 @904 NONAME |
||||
;SUniS905 @905 NONAME |
||||
;SUniS906 @906 NONAME |
||||
;SUniFindAfterUTF8Chr @907 NONAME |
||||
;SUniFindUTF8ChrStart @908 NONAME |
||||
;SUniConvertUTF16To909 @909 NONAME |
||||
;SUniConvertUTF16To910 @910 NONAME |
||||
;SUniConvertUTF16To911 @911 NONAME |
||||
;SUniConvert912 @912 NONAME |
||||
;SUniConvert913 @913 NONAME |
||||
;SUniConvert914 @914 NONAME |
||||
;SUniConvertUTF8ToWin @915 NONAME |
||||
; END |
||||
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 1999-2013 Ladislav Zezula |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in |
||||
all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||||
THE SOFTWARE. |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,217 @@
|
||||
/*****************************************************************************/ |
||||
/* FileStream.h Copyright (c) Ladislav Zezula 2012 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Description: Definitions for FileStream object */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 14.04.12 1.00 Lad The first version of FileStream.h */ |
||||
/*****************************************************************************/ |
||||
|
||||
#ifndef __FILESTREAM_H__ |
||||
#define __FILESTREAM_H__ |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function prototypes
|
||||
|
||||
typedef void (*STREAM_INIT)( |
||||
struct TFileStream * pStream // Pointer to an unopened stream
|
||||
); |
||||
|
||||
typedef bool (*STREAM_CREATE)( |
||||
struct TFileStream * pStream // Pointer to an unopened stream
|
||||
); |
||||
|
||||
typedef bool (*STREAM_OPEN)( |
||||
struct TFileStream * pStream, // Pointer to an unopened stream
|
||||
const TCHAR * szFileName, // Pointer to file name to be open
|
||||
DWORD dwStreamFlags // Stream flags
|
||||
); |
||||
|
||||
typedef bool (*STREAM_READ)( |
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it reads from the current position
|
||||
void * pvBuffer, // Pointer to data to be read
|
||||
DWORD dwBytesToRead // Number of bytes to read from the file
|
||||
); |
||||
|
||||
typedef bool (*STREAM_WRITE)( |
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pByteOffset, // Pointer to file byte offset. If NULL, it writes to the current position
|
||||
const void * pvBuffer, // Pointer to data to be written
|
||||
DWORD dwBytesToWrite // Number of bytes to read from the file
|
||||
); |
||||
|
||||
typedef bool (*STREAM_RESIZE)( |
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG FileSize // New size for the file, in bytes
|
||||
); |
||||
|
||||
typedef bool (*STREAM_GETSIZE)( |
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pFileSize // Receives the file size, in bytes
|
||||
); |
||||
|
||||
typedef bool (*STREAM_GETPOS)( |
||||
struct TFileStream * pStream, // Pointer to an open stream
|
||||
ULONGLONG * pByteOffset // Pointer to store current file position
|
||||
); |
||||
|
||||
typedef void (*STREAM_CLOSE)( |
||||
struct TFileStream * pStream // Pointer to an open stream
|
||||
); |
||||
|
||||
typedef bool (*BLOCK_READ)( |
||||
struct TFileStream * pStream, // Pointer to a block-oriented stream
|
||||
ULONGLONG StartOffset, // Byte offset of start of the block array
|
||||
ULONGLONG EndOffset, // End offset (either end of the block or end of the file)
|
||||
LPBYTE BlockBuffer, // Pointer to block-aligned buffer
|
||||
DWORD BytesNeeded, // Number of bytes that are really needed
|
||||
bool bAvailable // true if the block is available
|
||||
); |
||||
|
||||
typedef bool (*BLOCK_CHECK)( |
||||
struct TFileStream * pStream, // Pointer to a block-oriented stream
|
||||
ULONGLONG BlockOffset // Offset of the file to check
|
||||
); |
||||
|
||||
typedef void (*BLOCK_SAVEMAP)( |
||||
struct TFileStream * pStream // Pointer to a block-oriented stream
|
||||
); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local structures - partial file structure and bitmap footer
|
||||
|
||||
#define ID_FILE_BITMAP_FOOTER 0x33767470 // Signature of the file bitmap footer ('ptv3')
|
||||
#define DEFAULT_BLOCK_SIZE 0x00004000 // Default size of the stream block
|
||||
#define DEFAULT_BUILD_NUMBER 10958 // Build number for newly created partial MPQs
|
||||
|
||||
typedef struct _PART_FILE_HEADER |
||||
{ |
||||
DWORD PartialVersion; // Always set to 2
|
||||
char GameBuildNumber[0x20]; // Minimum build number of the game that can use this MPQ
|
||||
DWORD Flags; // Flags (details unknown)
|
||||
DWORD FileSizeLo; // Low 32 bits of the contained file size
|
||||
DWORD FileSizeHi; // High 32 bits of the contained file size
|
||||
DWORD BlockSize; // Size of one file block, in bytes
|
||||
|
||||
} PART_FILE_HEADER, *PPART_FILE_HEADER; |
||||
|
||||
// Structure describing the block-to-file map entry
|
||||
typedef struct _PART_FILE_MAP_ENTRY |
||||
{ |
||||
DWORD Flags; // 3 = the block is present in the file
|
||||
DWORD BlockOffsLo; // Low 32 bits of the block position in the file
|
||||
DWORD BlockOffsHi; // High 32 bits of the block position in the file
|
||||
DWORD LargeValueLo; // 64-bit value, meaning is unknown
|
||||
DWORD LargeValueHi; |
||||
|
||||
} PART_FILE_MAP_ENTRY, *PPART_FILE_MAP_ENTRY; |
||||
|
||||
typedef struct _FILE_BITMAP_FOOTER |
||||
{ |
||||
DWORD Signature; // 'ptv3' (ID_FILE_BITMAP_FOOTER)
|
||||
DWORD Version; // Unknown, seems to always have value of 3 (version?)
|
||||
DWORD BuildNumber; // Game build number for that MPQ
|
||||
DWORD MapOffsetLo; // Low 32-bits of the offset of the bit map
|
||||
DWORD MapOffsetHi; // High 32-bits of the offset of the bit map
|
||||
DWORD BlockSize; // Size of one block (usually 0x4000 bytes)
|
||||
|
||||
} FILE_BITMAP_FOOTER, *PFILE_BITMAP_FOOTER; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure for file stream
|
||||
|
||||
union TBaseProviderData |
||||
{ |
||||
struct |
||||
{ |
||||
ULONGLONG FileSize; // Size of the file
|
||||
ULONGLONG FilePos; // Current file position
|
||||
ULONGLONG FileTime; // Last write time
|
||||
HANDLE hFile; // File handle
|
||||
} File; |
||||
|
||||
struct |
||||
{ |
||||
ULONGLONG FileSize; // Size of the file
|
||||
ULONGLONG FilePos; // Current file position
|
||||
ULONGLONG FileTime; // Last write time
|
||||
LPBYTE pbFile; // Pointer to mapped view
|
||||
} Map; |
||||
|
||||
struct |
||||
{ |
||||
ULONGLONG FileSize; // Size of the file
|
||||
ULONGLONG FilePos; // Current file position
|
||||
ULONGLONG FileTime; // Last write time
|
||||
HANDLE hInternet; // Internet handle
|
||||
HANDLE hConnect; // Connection to the internet server
|
||||
} Http; |
||||
}; |
||||
|
||||
struct TFileStream |
||||
{ |
||||
// Stream provider functions
|
||||
STREAM_READ StreamRead; // Pointer to stream read function for this archive. Do not use directly.
|
||||
STREAM_WRITE StreamWrite; // Pointer to stream write function for this archive. Do not use directly.
|
||||
STREAM_RESIZE StreamResize; // Pointer to function changing file size
|
||||
STREAM_GETSIZE StreamGetSize; // Pointer to function returning file size
|
||||
STREAM_GETPOS StreamGetPos; // Pointer to function that returns current file position
|
||||
STREAM_CLOSE StreamClose; // Pointer to function closing the stream
|
||||
|
||||
// Block-oriented functions
|
||||
BLOCK_READ BlockRead; // Pointer to function reading one or more blocks
|
||||
BLOCK_CHECK BlockCheck; // Pointer to function checking whether the block is present
|
||||
|
||||
// Base provider functions
|
||||
STREAM_CREATE BaseCreate; // Pointer to base create function
|
||||
STREAM_OPEN BaseOpen; // Pointer to base open function
|
||||
STREAM_READ BaseRead; // Read from the stream
|
||||
STREAM_WRITE BaseWrite; // Write to the stream
|
||||
STREAM_RESIZE BaseResize; // Pointer to function changing file size
|
||||
STREAM_GETSIZE BaseGetSize; // Pointer to function returning file size
|
||||
STREAM_GETPOS BaseGetPos; // Pointer to function that returns current file position
|
||||
STREAM_CLOSE BaseClose; // Pointer to function closing the stream
|
||||
|
||||
// Base provider data (file size, file position)
|
||||
TBaseProviderData Base; |
||||
|
||||
// Stream provider data
|
||||
TFileStream * pMaster; // Master stream (e.g. MPQ on a web server)
|
||||
TCHAR * szFileName; // File name (self-relative pointer)
|
||||
|
||||
ULONGLONG StreamSize; // Stream size (can be less than file size)
|
||||
ULONGLONG StreamPos; // Stream position
|
||||
DWORD BuildNumber; // Game build number
|
||||
DWORD dwFlags; // Stream flags
|
||||
|
||||
// Followed by stream provider data, with variable length
|
||||
}; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structures for block-oriented stream
|
||||
|
||||
struct TBlockStream : public TFileStream |
||||
{ |
||||
SFILE_DOWNLOAD_CALLBACK pfnCallback; // Callback for downloading
|
||||
void * FileBitmap; // Array of bits for file blocks
|
||||
void * UserData; // User data to be passed to the download callback
|
||||
DWORD BitmapSize; // Size of the file bitmap (in bytes)
|
||||
DWORD BlockSize; // Size of one block, in bytes
|
||||
DWORD BlockCount; // Number of data blocks in the file
|
||||
DWORD IsComplete; // If nonzero, no blocks are missing
|
||||
DWORD IsModified; // nonzero if the bitmap has been modified
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Structure for encrypted stream
|
||||
|
||||
#define MPQE_CHUNK_SIZE 0x40 // Size of one chunk to be decrypted
|
||||
|
||||
struct TEncryptedStream : public TBlockStream |
||||
{ |
||||
BYTE Key[MPQE_CHUNK_SIZE]; // File key
|
||||
}; |
||||
|
||||
#endif // __FILESTREAM_H__
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,618 @@
|
||||
/*****************************************************************************/ |
||||
/* SBaseSubTypes.cpp Copyright (c) Ladislav Zezula 2013 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Conversion routines for archive formats that are similar to MPQ format */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 02.11.11 1.00 Lad The first version of SBaseSubTypes.cpp */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define __STORMLIB_SELF__ |
||||
#include "StormLib.h" |
||||
#include "StormCommon.h" |
||||
|
||||
/*****************************************************************************/ |
||||
/* */ |
||||
/* Support for SQP file format (War of the Immortals) */ |
||||
/* */ |
||||
/*****************************************************************************/ |
||||
|
||||
typedef struct _TSQPHeader |
||||
{ |
||||
// The ID_MPQ ('MPQ\x1A') signature
|
||||
DWORD dwID;
|
||||
|
||||
// Size of the archive header
|
||||
DWORD dwHeaderSize;
|
||||
|
||||
// 32-bit size of MPQ archive
|
||||
DWORD dwArchiveSize; |
||||
|
||||
// Offset to the beginning of the hash table, relative to the beginning of the archive.
|
||||
DWORD dwHashTablePos; |
||||
|
||||
// Offset to the beginning of the block table, relative to the beginning of the archive.
|
||||
DWORD dwBlockTablePos; |
||||
|
||||
// Number of entries in the hash table. Must be a power of two, and must be less than 2^16 for
|
||||
// the original MoPaQ format, or less than 2^20 for the Burning Crusade format.
|
||||
DWORD dwHashTableSize; |
||||
|
||||
// Number of entries in the block table
|
||||
DWORD dwBlockTableSize; |
||||
|
||||
// Must be zero for SQP files
|
||||
USHORT wFormatVersion; |
||||
|
||||
// Power of two exponent specifying the number of 512-byte disk sectors in each file sector
|
||||
// in the archive. The size of each file sector in the archive is 512 * 2 ^ wSectorSize.
|
||||
USHORT wSectorSize; |
||||
|
||||
} TSQPHeader; |
||||
|
||||
typedef struct _TSQPHash |
||||
{ |
||||
// Most likely the lcLocale+wPlatform.
|
||||
DWORD dwAlwaysZero; |
||||
|
||||
// If the hash table entry is valid, this is the index into the block table of the file.
|
||||
// Otherwise, one of the following two values:
|
||||
// - FFFFFFFFh: Hash table entry is empty, and has always been empty.
|
||||
// Terminates searches for a given file.
|
||||
// - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
|
||||
// Does not terminate searches for a given file.
|
||||
DWORD dwBlockIndex; |
||||
|
||||
// The hash of the file path, using method A.
|
||||
DWORD dwName1; |
||||
|
||||
// The hash of the file path, using method B.
|
||||
DWORD dwName2; |
||||
|
||||
} TSQPHash; |
||||
|
||||
typedef struct _TSQPBlock |
||||
{ |
||||
// Offset of the beginning of the file, relative to the beginning of the archive.
|
||||
DWORD dwFilePos; |
||||
|
||||
// Flags for the file. See MPQ_FILE_XXXX constants
|
||||
DWORD dwFlags;
|
||||
|
||||
// Compressed file size
|
||||
DWORD dwCSize; |
||||
|
||||
// Uncompressed file size
|
||||
DWORD dwFSize;
|
||||
|
||||
} TSQPBlock; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions - SQP file format
|
||||
|
||||
// This function converts SQP file header into MPQ file header
|
||||
int ConvertSqpHeaderToFormat4( |
||||
TMPQArchive * ha, |
||||
ULONGLONG FileSize, |
||||
DWORD dwFlags) |
||||
{ |
||||
TSQPHeader * pSqpHeader = (TSQPHeader *)ha->HeaderData; |
||||
TMPQHeader Header; |
||||
|
||||
// SQP files from War of the Immortal use MPQ file format with slightly
|
||||
// modified structure. These fields have different position:
|
||||
//
|
||||
// Offset TMPQHeader TSQPHeader
|
||||
// ------ ---------- -----------
|
||||
// 000C wFormatVersion dwHashTablePos (lo)
|
||||
// 000E wSectorSize dwHashTablePos (hi)
|
||||
// 001C dwBlockTableSize (lo) wBlockSize
|
||||
// 001E dwHashTableSize (hi) wFormatVersion
|
||||
|
||||
// Can't open the archive with certain flags
|
||||
if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) |
||||
return ERROR_FILE_CORRUPT; |
||||
|
||||
// The file must not be greater than 4 GB
|
||||
if((FileSize >> 0x20) != 0) |
||||
return ERROR_FILE_CORRUPT; |
||||
|
||||
// Translate the SQP header into a MPQ header
|
||||
memset(&Header, 0, sizeof(TMPQHeader)); |
||||
Header.dwID = BSWAP_INT32_UNSIGNED(pSqpHeader->dwID); |
||||
Header.dwHeaderSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHeaderSize); |
||||
Header.dwArchiveSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwArchiveSize); |
||||
Header.dwHashTablePos = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHashTablePos); |
||||
Header.dwBlockTablePos = BSWAP_INT32_UNSIGNED(pSqpHeader->dwBlockTablePos); |
||||
Header.dwHashTableSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwHashTableSize); |
||||
Header.dwBlockTableSize = BSWAP_INT32_UNSIGNED(pSqpHeader->dwBlockTableSize); |
||||
Header.wFormatVersion = BSWAP_INT16_UNSIGNED(pSqpHeader->wFormatVersion); |
||||
Header.wSectorSize = BSWAP_INT16_UNSIGNED(pSqpHeader->wSectorSize); |
||||
|
||||
// Verify the SQP header
|
||||
if(Header.dwID == ID_MPQ && Header.dwHeaderSize == sizeof(TSQPHeader) && Header.dwArchiveSize == FileSize) |
||||
{ |
||||
// Check for fixed values of version and sector size
|
||||
if(Header.wFormatVersion == MPQ_FORMAT_VERSION_1 && Header.wSectorSize == 3) |
||||
{ |
||||
// Initialize the fields of 3.0 header
|
||||
Header.ArchiveSize64 = Header.dwArchiveSize; |
||||
Header.HashTableSize64 = Header.dwHashTableSize * sizeof(TMPQHash); |
||||
Header.BlockTableSize64 = Header.dwBlockTableSize * sizeof(TMPQBlock); |
||||
|
||||
// Copy the converted MPQ header back
|
||||
memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader)); |
||||
|
||||
// Mark this file as SQP file
|
||||
ha->pfnHashString = HashStringSlash; |
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY; |
||||
ha->dwSubType = MPQ_SUBTYPE_SQP; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
} |
||||
|
||||
return ERROR_FILE_CORRUPT; |
||||
} |
||||
|
||||
void * LoadSqpTable(TMPQArchive * ha, DWORD dwByteOffset, DWORD cbTableSize, DWORD dwKey) |
||||
{ |
||||
ULONGLONG ByteOffset; |
||||
LPBYTE pbSqpTable; |
||||
|
||||
// Allocate buffer for the table
|
||||
pbSqpTable = STORM_ALLOC(BYTE, cbTableSize); |
||||
if(pbSqpTable != NULL) |
||||
{ |
||||
// Load the table
|
||||
ByteOffset = ha->MpqPos + dwByteOffset; |
||||
if(FileStream_Read(ha->pStream, &ByteOffset, pbSqpTable, cbTableSize)) |
||||
{ |
||||
// Decrypt the SQP table
|
||||
DecryptMpqBlock(pbSqpTable, cbTableSize, dwKey); |
||||
return pbSqpTable; |
||||
} |
||||
|
||||
// Free the table
|
||||
STORM_FREE(pbSqpTable); |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
TMPQHash * LoadSqpHashTable(TMPQArchive * ha) |
||||
{ |
||||
TMPQHeader * pHeader = ha->pHeader; |
||||
TSQPHash * pSqpHashTable; |
||||
TSQPHash * pSqpHashEnd; |
||||
TSQPHash * pSqpHash; |
||||
TMPQHash * pMpqHash; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Load the hash table
|
||||
pSqpHashTable = (TSQPHash *)LoadSqpTable(ha, pHeader->dwHashTablePos, pHeader->dwHashTableSize * sizeof(TSQPHash), MPQ_KEY_HASH_TABLE); |
||||
if(pSqpHashTable != NULL) |
||||
{ |
||||
// Parse the entire hash table and convert it to MPQ hash table
|
||||
pSqpHashEnd = pSqpHashTable + pHeader->dwHashTableSize; |
||||
pMpqHash = (TMPQHash *)pSqpHashTable; |
||||
for(pSqpHash = pSqpHashTable; pSqpHash < pSqpHashEnd; pSqpHash++, pMpqHash++) |
||||
{ |
||||
// Ignore free entries
|
||||
if(pSqpHash->dwBlockIndex != HASH_ENTRY_FREE) |
||||
{ |
||||
// Check block index against the size of the block table
|
||||
if(pHeader->dwBlockTableSize <= MPQ_BLOCK_INDEX(pSqpHash) && pSqpHash->dwBlockIndex < HASH_ENTRY_DELETED) |
||||
nError = ERROR_FILE_CORRUPT; |
||||
|
||||
// We do not support nonzero locale and platform ID
|
||||
if(pSqpHash->dwAlwaysZero != 0 && pSqpHash->dwAlwaysZero != HASH_ENTRY_FREE) |
||||
nError = ERROR_FILE_CORRUPT; |
||||
|
||||
// Store the file name hash
|
||||
pMpqHash->dwName1 = pSqpHash->dwName1; |
||||
pMpqHash->dwName2 = pSqpHash->dwName2; |
||||
|
||||
// Store the rest. Note that this must be done last,
|
||||
// because block index corresponds to pMpqHash->dwName2
|
||||
pMpqHash->dwBlockIndex = MPQ_BLOCK_INDEX(pSqpHash); |
||||
pMpqHash->Platform = 0; |
||||
pMpqHash->lcLocale = 0; |
||||
} |
||||
} |
||||
|
||||
// If an error occured, we need to free the hash table
|
||||
if(nError != ERROR_SUCCESS) |
||||
{ |
||||
STORM_FREE(pSqpHashTable); |
||||
pSqpHashTable = NULL; |
||||
} |
||||
} |
||||
|
||||
// Return the converted hash table (or NULL on failure)
|
||||
return (TMPQHash *)pSqpHashTable; |
||||
} |
||||
|
||||
// Loads the SQP Block table and converts it to a MPQ block table
|
||||
TMPQBlock * LoadSqpBlockTable(TMPQArchive * ha) |
||||
{ |
||||
TMPQHeader * pHeader = ha->pHeader; |
||||
TSQPBlock * pSqpBlockTable; |
||||
TSQPBlock * pSqpBlockEnd; |
||||
TSQPBlock * pSqpBlock; |
||||
TMPQBlock * pMpqBlock; |
||||
DWORD dwFlags; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Load the hash table
|
||||
pSqpBlockTable = (TSQPBlock *)LoadSqpTable(ha, pHeader->dwBlockTablePos, pHeader->dwBlockTableSize * sizeof(TSQPBlock), MPQ_KEY_BLOCK_TABLE); |
||||
if(pSqpBlockTable != NULL) |
||||
{ |
||||
// Parse the entire hash table and convert it to MPQ hash table
|
||||
pSqpBlockEnd = pSqpBlockTable + pHeader->dwBlockTableSize; |
||||
pMpqBlock = (TMPQBlock *)pSqpBlockTable; |
||||
for(pSqpBlock = pSqpBlockTable; pSqpBlock < pSqpBlockEnd; pSqpBlock++, pMpqBlock++) |
||||
{ |
||||
// Check for valid flags
|
||||
if(pSqpBlock->dwFlags & ~MPQ_FILE_VALID_FLAGS) |
||||
nError = ERROR_FILE_CORRUPT; |
||||
|
||||
// Convert SQP block table entry to MPQ block table entry
|
||||
dwFlags = pSqpBlock->dwFlags; |
||||
pMpqBlock->dwCSize = pSqpBlock->dwCSize; |
||||
pMpqBlock->dwFSize = pSqpBlock->dwFSize; |
||||
pMpqBlock->dwFlags = dwFlags; |
||||
} |
||||
|
||||
// If an error occured, we need to free the hash table
|
||||
if(nError != ERROR_SUCCESS) |
||||
{ |
||||
STORM_FREE(pSqpBlockTable); |
||||
pSqpBlockTable = NULL; |
||||
} |
||||
} |
||||
|
||||
// Return the converted hash table (or NULL on failure)
|
||||
return (TMPQBlock *)pSqpBlockTable; |
||||
} |
||||
|
||||
/*****************************************************************************/ |
||||
/* */ |
||||
/* Support for MPK file format (Longwu Online) */ |
||||
/* */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define MPK_FILE_UNKNOWN_0001 0x00000001 // Seems to be always present
|
||||
#define MPK_FILE_UNKNOWN_0010 0x00000010 // Seems to be always present
|
||||
#define MPK_FILE_COMPRESSED 0x00000100 // Indicates a compressed file
|
||||
#define MPK_FILE_UNKNOWN_2000 0x00002000 // Seems to be always present
|
||||
#define MPK_FILE_EXISTS 0x01000000 // Seems to be always present
|
||||
|
||||
typedef struct _TMPKHeader |
||||
{ |
||||
// The ID_MPK ('MPK\x1A') signature
|
||||
DWORD dwID; |
||||
|
||||
// Contains '2000'
|
||||
DWORD dwVersion; |
||||
|
||||
// 32-bit size of the archive
|
||||
DWORD dwArchiveSize; |
||||
|
||||
// Size of the archive header
|
||||
DWORD dwHeaderSize; |
||||
|
||||
DWORD dwHashTablePos; |
||||
DWORD dwHashTableSize; |
||||
DWORD dwBlockTablePos; |
||||
DWORD dwBlockTableSize; |
||||
DWORD dwUnknownPos; |
||||
DWORD dwUnknownSize; |
||||
} TMPKHeader; |
||||
|
||||
|
||||
typedef struct _TMPKHash |
||||
{ |
||||
// The hash of the file path, using method A.
|
||||
DWORD dwName1; |
||||
|
||||
// The hash of the file path, using method B.
|
||||
DWORD dwName2; |
||||
|
||||
// The hash of the file path, using method C.
|
||||
DWORD dwName3; |
||||
|
||||
// If the hash table entry is valid, this is the index into the block table of the file.
|
||||
// Otherwise, one of the following two values:
|
||||
// - FFFFFFFFh: Hash table entry is empty, and has always been empty.
|
||||
// Terminates searches for a given file.
|
||||
// - FFFFFFFEh: Hash table entry is empty, but was valid at some point (a deleted file).
|
||||
// Does not terminate searches for a given file.
|
||||
DWORD dwBlockIndex; |
||||
|
||||
} TMPKHash; |
||||
|
||||
typedef struct _TMPKBlock |
||||
{ |
||||
DWORD dwFlags; // 0x1121 - Compressed , 0x1120 - Not compressed
|
||||
DWORD dwFilePos; // Offset of the beginning of the file, relative to the beginning of the archive.
|
||||
DWORD dwFSize; // Uncompressed file size
|
||||
DWORD dwCSize; // Compressed file size
|
||||
DWORD dwUnknown; // 0x86364E6D
|
||||
} TMPKBlock; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local variables - MPK file format
|
||||
|
||||
static const unsigned char MpkDecryptionKey[512] = |
||||
{ |
||||
0x60, 0x20, 0x29, 0xE1, 0x01, 0xCE, 0xAA, 0xFE, 0xA3, 0xAB, 0x8E, 0x30, 0xAF, 0x02, 0xD1, 0x7D, |
||||
0x41, 0x24, 0x06, 0xBD, 0xAE, 0xBE, 0x43, 0xC3, 0xBA, 0xB7, 0x08, 0x13, 0x51, 0xCF, 0xF8, 0xF7, |
||||
0x25, 0x42, 0xA5, 0x4A, 0xDA, 0x0F, 0x52, 0x1C, 0x90, 0x3B, 0x63, 0x49, 0x36, 0xF6, 0xDD, 0x1B, |
||||
0xEA, 0x58, 0xD4, 0x40, 0x70, 0x61, 0x55, 0x09, 0xCD, 0x0B, 0xA2, 0x4B, 0x68, 0x2C, 0x8A, 0xF1, |
||||
0x3C, 0x3A, 0x65, 0xBB, 0xA1, 0xA8, 0x23, 0x97, 0xFD, 0x15, 0x00, 0x94, 0x88, 0x33, 0x59, 0xE9, |
||||
0xFB, 0x69, 0x21, 0xEF, 0x85, 0x5B, 0x57, 0x6C, 0xFA, 0xB5, 0xEE, 0xB8, 0x71, 0xDC, 0xB1, 0x38, |
||||
0x0C, 0x0A, 0x5C, 0x56, 0xC9, 0xB4, 0x84, 0x17, 0x1E, 0xE5, 0xD3, 0x5A, 0xCC, 0xFC, 0x11, 0x86, |
||||
0x7F, 0x45, 0x4F, 0x54, 0xC8, 0x8D, 0x73, 0x89, 0x79, 0x5D, 0xB3, 0xBF, 0xB9, 0xE3, 0x93, 0xE4, |
||||
0x6F, 0x35, 0x2D, 0x46, 0xF2, 0x76, 0xC5, 0x7E, 0xE2, 0xA4, 0xE6, 0xD9, 0x6E, 0x48, 0x34, 0x2B, |
||||
0xC6, 0x5F, 0xBC, 0xA0, 0x6D, 0x0D, 0x47, 0x6B, 0x95, 0x96, 0x92, 0x91, 0xB2, 0x27, 0xEB, 0x9E, |
||||
0xEC, 0x8F, 0xDF, 0x9C, 0x74, 0x99, 0x64, 0xF5, 0xFF, 0x28, 0xB6, 0x37, 0xF3, 0x7C, 0x81, 0x03, |
||||
0x44, 0x62, 0x1F, 0xDB, 0x04, 0x7B, 0xB0, 0x9B, 0x31, 0xA7, 0xDE, 0x78, 0x9F, 0xAD, 0x0E, 0x3F, |
||||
0x3E, 0x4D, 0xC7, 0xD7, 0x39, 0x19, 0x5E, 0xC2, 0xD0, 0xAC, 0xE8, 0x1A, 0x87, 0x8B, 0x07, 0x05, |
||||
0x22, 0xED, 0x72, 0x2E, 0x1D, 0xC1, 0xA9, 0xD6, 0xE0, 0x83, 0xD5, 0xD8, 0xCB, 0x80, 0xF0, 0x66, |
||||
0x7A, 0x9D, 0x50, 0xF9, 0x10, 0x4E, 0x16, 0x14, 0x77, 0x75, 0x6A, 0x67, 0xD2, 0xC0, 0xA6, 0xC4, |
||||
0x53, 0x8C, 0x32, 0xCA, 0x82, 0x2A, 0x18, 0x9A, 0xF4, 0x4C, 0x3D, 0x26, 0x12, 0xE7, 0x98, 0x2F, |
||||
0x4A, 0x04, 0x0D, 0xAF, 0xB4, 0xCF, 0x12, 0xCE, 0x1A, 0x37, 0x61, 0x39, 0x60, 0x95, 0xBE, 0x25, |
||||
0xE4, 0x6E, 0xFC, 0x1B, 0xE7, 0x49, 0xE6, 0x67, 0xF6, 0xC5, 0xCB, 0x2F, 0x27, 0xD4, 0x68, 0xB2, |
||||
0x01, 0x52, 0xD0, 0x46, 0x11, 0x20, 0xFB, 0x9D, 0xA9, 0x02, 0xF5, 0x8F, 0x3D, 0x82, 0xD3, 0xFF, |
||||
0x0B, 0xB8, 0xF2, 0x4D, 0x8E, 0x81, 0x2C, 0xAB, 0x5F, 0xC4, 0x41, 0x29, 0x40, 0xFA, 0xC0, 0xBF, |
||||
0x33, 0x10, 0x21, 0x16, 0xB0, 0x71, 0x83, 0x96, 0x8D, 0x2B, 0x23, 0x3B, 0xF9, 0xC1, 0xE5, 0x72, |
||||
0xE2, 0x1C, 0x26, 0xF0, 0x73, 0x36, 0x63, 0x56, 0x31, 0x4E, 0x6B, 0x55, 0x62, 0x79, 0xC6, 0x91, |
||||
0x00, 0x35, 0xB1, 0x2A, 0xA6, 0x42, 0xDF, 0xEB, 0x3C, 0x51, 0xEA, 0x97, 0x57, 0x94, 0x8C, 0x80, |
||||
0x34, 0x5C, 0xD2, 0x76, 0xA4, 0xE9, 0x85, 0xE8, 0xBB, 0x78, 0xE0, 0xB5, 0xAD, 0x0F, 0x87, 0x70, |
||||
0xDD, 0xAE, 0xF4, 0xD9, 0x66, 0x54, 0x6F, 0xCC, 0x4C, 0x77, 0x3E, 0xCD, 0xF1, 0x75, 0x0A, 0xA1, |
||||
0x28, 0x9B, 0x9A, 0x7E, 0x4B, 0x98, 0x99, 0x47, 0xFE, 0xA5, 0xF7, 0xB7, 0xA3, 0xE1, 0x9F, 0xBC, |
||||
0x93, 0x44, 0x3A, 0x08, 0x89, 0x22, 0xEE, 0xB9, 0x45, 0xD6, 0x06, 0x09, 0xC9, 0xBD, 0x14, 0x0C, |
||||
0xB6, 0x5E, 0x9C, 0x7A, 0x65, 0x59, 0xAA, 0x19, 0x5B, 0x7C, 0x18, 0x43, 0x92, 0x13, 0x15, 0x7B, |
||||
0xED, 0xD5, 0xC7, 0x17, 0xEF, 0x86, 0x90, 0xC2, 0x74, 0x64, 0xF3, 0xDC, 0x6C, 0x38, 0x05, 0x1D, |
||||
0xC8, 0x0E, 0xEC, 0x6A, 0x32, 0xDA, 0xD7, 0xC3, 0xDB, 0x8B, 0x24, 0xB3, 0x5D, 0x2E, 0xBA, 0xA2, |
||||
0xD8, 0x03, 0x88, 0x7D, 0x7F, 0x69, 0x8A, 0xFD, 0xCA, 0x4F, 0x30, 0x9E, 0xA0, 0xD1, 0x5A, 0x53, |
||||
0xDE, 0x3F, 0x84, 0xAC, 0xF8, 0xA7, 0x2D, 0x1F, 0x1E, 0xE3, 0x58, 0x50, 0x6D, 0x48, 0x07, 0xA8 |
||||
}; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Functions - MPK file format
|
||||
|
||||
// This function converts MPK file header into MPQ file header
|
||||
int ConvertMpkHeaderToFormat4( |
||||
TMPQArchive * ha, |
||||
ULONGLONG FileSize, |
||||
DWORD dwFlags) |
||||
{ |
||||
TMPKHeader * pMpkHeader = (TMPKHeader *)ha->HeaderData; |
||||
TMPQHeader Header; |
||||
|
||||
// Can't open the archive with certain flags
|
||||
if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) |
||||
return ERROR_FILE_CORRUPT; |
||||
|
||||
// Translate the MPK header into a MPQ header
|
||||
// Note: Hash table size and block table size are in bytes, not in entries
|
||||
memset(&Header, 0, sizeof(TMPQHeader)); |
||||
Header.dwID = BSWAP_INT32_UNSIGNED(pMpkHeader->dwID); |
||||
Header.dwArchiveSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwArchiveSize); |
||||
Header.dwHeaderSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHeaderSize); |
||||
Header.dwHashTablePos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHashTablePos); |
||||
Header.dwHashTableSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwHashTableSize) / sizeof(TMPKHash); |
||||
Header.dwBlockTablePos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwBlockTablePos); |
||||
Header.dwBlockTableSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwBlockTableSize) / sizeof(TMPKBlock); |
||||
// Header.dwUnknownPos = BSWAP_INT32_UNSIGNED(pMpkHeader->dwUnknownPos);
|
||||
// Header.dwUnknownSize = BSWAP_INT32_UNSIGNED(pMpkHeader->dwUnknownSize);
|
||||
assert(Header.dwHeaderSize == sizeof(TMPKHeader)); |
||||
|
||||
// Verify the MPK header
|
||||
if(Header.dwID == ID_MPK && Header.dwHeaderSize == sizeof(TMPKHeader) && Header.dwArchiveSize == (DWORD)FileSize) |
||||
{ |
||||
// The header ID must be ID_MPQ
|
||||
Header.dwID = ID_MPQ; |
||||
Header.wFormatVersion = MPQ_FORMAT_VERSION_1; |
||||
Header.wSectorSize = 3; |
||||
|
||||
// Initialize the fields of 3.0 header
|
||||
Header.ArchiveSize64 = Header.dwArchiveSize; |
||||
Header.HashTableSize64 = Header.dwHashTableSize * sizeof(TMPQHash); |
||||
Header.BlockTableSize64 = Header.dwBlockTableSize * sizeof(TMPQBlock); |
||||
|
||||
// Copy the converted MPQ header back
|
||||
memcpy(ha->HeaderData, &Header, sizeof(TMPQHeader)); |
||||
|
||||
// Mark this file as MPK file
|
||||
ha->pfnHashString = HashStringLower; |
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY; |
||||
ha->dwSubType = MPQ_SUBTYPE_MPK; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
return ERROR_FILE_CORRUPT; |
||||
} |
||||
|
||||
// Attempts to search a free hash entry in the hash table being converted.
|
||||
// The created hash table must always be of nonzero size,
|
||||
// should have no duplicated items and no deleted entries
|
||||
TMPQHash * FindFreeHashEntry(TMPQHash * pHashTable, DWORD dwHashTableSize, DWORD dwStartIndex) |
||||
{ |
||||
TMPQHash * pHash; |
||||
DWORD dwIndex; |
||||
|
||||
// Set the initial index
|
||||
dwStartIndex = dwIndex = (dwStartIndex & (dwHashTableSize - 1)); |
||||
assert(dwHashTableSize != 0); |
||||
|
||||
// Search the hash table and return the found entries in the following priority:
|
||||
for(;;) |
||||
{ |
||||
// We are not expecting to find matching entry in the hash table being built
|
||||
// We are not expecting to find deleted entry either
|
||||
pHash = pHashTable + dwIndex; |
||||
|
||||
// If we found a free entry, we need to stop searching
|
||||
if(pHash->dwBlockIndex == HASH_ENTRY_FREE) |
||||
return pHash; |
||||
|
||||
// Move to the next hash entry.
|
||||
// If we reached the starting entry, it's failure.
|
||||
dwIndex = (dwIndex + 1) & (dwHashTableSize - 1); |
||||
if(dwIndex == dwStartIndex) |
||||
break; |
||||
} |
||||
|
||||
// We haven't found anything
|
||||
assert(false); |
||||
return NULL; |
||||
} |
||||
|
||||
void DecryptMpkTable(void * pvMpkTable, size_t cbSize) |
||||
{ |
||||
LPBYTE pbMpkTable = (LPBYTE)pvMpkTable; |
||||
|
||||
for(size_t i = 0; i < cbSize; i++) |
||||
pbMpkTable[i] = MpkDecryptionKey[pbMpkTable[i]]; |
||||
} |
||||
|
||||
void * LoadMpkTable(TMPQArchive * ha, DWORD dwByteOffset, DWORD cbTableSize) |
||||
{ |
||||
ULONGLONG ByteOffset; |
||||
LPBYTE pbMpkTable = NULL; |
||||
|
||||
// Allocate space for the table
|
||||
pbMpkTable = STORM_ALLOC(BYTE, cbTableSize); |
||||
if(pbMpkTable != NULL) |
||||
{ |
||||
// Load and the MPK hash table
|
||||
ByteOffset = ha->MpqPos + dwByteOffset; |
||||
if(FileStream_Read(ha->pStream, &ByteOffset, pbMpkTable, cbTableSize)) |
||||
{ |
||||
// Decrypt the table
|
||||
DecryptMpkTable(pbMpkTable, cbTableSize); |
||||
return pbMpkTable; |
||||
} |
||||
|
||||
// Free the MPK table
|
||||
STORM_FREE(pbMpkTable); |
||||
pbMpkTable = NULL; |
||||
} |
||||
|
||||
// Return the table
|
||||
return pbMpkTable; |
||||
} |
||||
|
||||
TMPQHash * LoadMpkHashTable(TMPQArchive * ha) |
||||
{ |
||||
TMPQHeader * pHeader = ha->pHeader; |
||||
TMPQHash * pHashTable = NULL; |
||||
TMPKHash * pMpkHash; |
||||
TMPQHash * pHash = NULL; |
||||
DWORD dwHashTableSize = pHeader->dwHashTableSize; |
||||
|
||||
// MPKs use different hash table searching.
|
||||
// Instead of using MPQ_HASH_TABLE_INDEX hash as index,
|
||||
// they store the value directly in the hash table.
|
||||
// Also for faster searching, the hash table is sorted ascending by the value
|
||||
|
||||
// Load and decrypt the MPK hash table.
|
||||
pMpkHash = (TMPKHash *)LoadMpkTable(ha, pHeader->dwHashTablePos, pHeader->dwHashTableSize * sizeof(TMPKHash)); |
||||
if(pMpkHash != NULL) |
||||
{ |
||||
// Calculate the hash table size as if it was real MPQ hash table
|
||||
pHeader->dwHashTableSize = GetNearestPowerOfTwo(pHeader->dwHashTableSize); |
||||
pHeader->HashTableSize64 = pHeader->dwHashTableSize * sizeof(TMPQHash); |
||||
|
||||
// Now allocate table that will serve like a true MPQ hash table,
|
||||
// so we translate the MPK hash table to MPQ hash table
|
||||
pHashTable = STORM_ALLOC(TMPQHash, pHeader->dwHashTableSize); |
||||
if(pHashTable != NULL) |
||||
{ |
||||
// Set the entire hash table to free
|
||||
memset(pHashTable, 0xFF, (size_t)pHeader->HashTableSize64); |
||||
|
||||
// Copy the MPK hash table into MPQ hash table
|
||||
for(DWORD i = 0; i < dwHashTableSize; i++) |
||||
{ |
||||
// Finds the free hash entry in the hash table
|
||||
// We don't expect any errors here, because we are putting files to empty hash table
|
||||
pHash = FindFreeHashEntry(pHashTable, pHeader->dwHashTableSize, pMpkHash[i].dwName1); |
||||
assert(pHash->dwBlockIndex == HASH_ENTRY_FREE); |
||||
|
||||
// Copy the MPK hash entry to the hash table
|
||||
pHash->dwBlockIndex = pMpkHash[i].dwBlockIndex; |
||||
pHash->Platform = 0; |
||||
pHash->lcLocale = 0; |
||||
pHash->dwName1 = pMpkHash[i].dwName2; |
||||
pHash->dwName2 = pMpkHash[i].dwName3; |
||||
} |
||||
} |
||||
|
||||
// Free the temporary hash table
|
||||
STORM_FREE(pMpkHash); |
||||
} |
||||
|
||||
return pHashTable; |
||||
} |
||||
|
||||
static DWORD ConvertMpkFlagsToMpqFlags(DWORD dwMpkFlags) |
||||
{ |
||||
DWORD dwMpqFlags = MPQ_FILE_EXISTS; |
||||
|
||||
// Check for flags that are always present
|
||||
assert((dwMpkFlags & MPK_FILE_UNKNOWN_0001) != 0); |
||||
assert((dwMpkFlags & MPK_FILE_UNKNOWN_0010) != 0); |
||||
assert((dwMpkFlags & MPK_FILE_UNKNOWN_2000) != 0); |
||||
assert((dwMpkFlags & MPK_FILE_EXISTS) != 0); |
||||
|
||||
// Append the compressed flag
|
||||
dwMpqFlags |= (dwMpkFlags & MPK_FILE_COMPRESSED) ? MPQ_FILE_COMPRESS : 0; |
||||
|
||||
// All files in the MPQ seem to be single unit files
|
||||
dwMpqFlags |= MPQ_FILE_ENCRYPTED | MPQ_FILE_SINGLE_UNIT; |
||||
|
||||
return dwMpqFlags; |
||||
} |
||||
|
||||
TMPQBlock * LoadMpkBlockTable(TMPQArchive * ha) |
||||
{ |
||||
TMPQHeader * pHeader = ha->pHeader; |
||||
TMPKBlock * pMpkBlockTable; |
||||
TMPKBlock * pMpkBlockEnd; |
||||
TMPQBlock * pBlockTable = NULL; |
||||
TMPKBlock * pMpkBlock; |
||||
TMPQBlock * pMpqBlock; |
||||
|
||||
// Load and decrypt the MPK block table
|
||||
pMpkBlockTable = pMpkBlock = (TMPKBlock *)LoadMpkTable(ha, pHeader->dwBlockTablePos, pHeader->dwBlockTableSize * sizeof(TMPKBlock)); |
||||
if(pMpkBlockTable != NULL) |
||||
{ |
||||
// Allocate buffer for MPQ-like block table
|
||||
pBlockTable = pMpqBlock = STORM_ALLOC(TMPQBlock, pHeader->dwBlockTableSize); |
||||
if(pBlockTable != NULL) |
||||
{ |
||||
// Convert the MPK block table to MPQ block table
|
||||
pMpkBlockEnd = pMpkBlockTable + pHeader->dwBlockTableSize; |
||||
while(pMpkBlock < pMpkBlockEnd) |
||||
{ |
||||
// Translate the MPK block table entry to MPQ block table entry
|
||||
pMpqBlock->dwFilePos = pMpkBlock->dwFilePos; |
||||
pMpqBlock->dwCSize = pMpkBlock->dwCSize; |
||||
pMpqBlock->dwFSize = pMpkBlock->dwFSize; |
||||
pMpqBlock->dwFlags = ConvertMpkFlagsToMpqFlags(pMpkBlock->dwFlags); |
||||
|
||||
// Move both
|
||||
pMpkBlock++; |
||||
pMpqBlock++; |
||||
} |
||||
} |
||||
|
||||
// Free the MPK block table
|
||||
STORM_FREE(pMpkBlockTable); |
||||
} |
||||
|
||||
return pBlockTable; |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@
|
||||
/*****************************************************************************/ |
||||
/* SFileExtractFile.cpp Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Simple extracting utility */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 20.06.03 1.00 Lad The first version of SFileExtractFile.cpp */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define __STORMLIB_SELF__ |
||||
#include "StormLib.h" |
||||
#include "StormCommon.h" |
||||
|
||||
bool WINAPI SFileExtractFile(HANDLE hMpq, const char * szToExtract, const TCHAR * szExtracted, DWORD dwSearchScope) |
||||
{ |
||||
TFileStream * pLocalFile = NULL; |
||||
HANDLE hMpqFile = NULL; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Open the MPQ file
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
if(!SFileOpenFileEx(hMpq, szToExtract, dwSearchScope, &hMpqFile)) |
||||
nError = GetLastError(); |
||||
} |
||||
|
||||
// Create the local file
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
pLocalFile = FileStream_CreateFile(szExtracted, 0); |
||||
if(pLocalFile == NULL) |
||||
nError = GetLastError(); |
||||
} |
||||
|
||||
// Copy the file's content
|
||||
while(nError == ERROR_SUCCESS) |
||||
{ |
||||
char szBuffer[0x1000]; |
||||
DWORD dwTransferred = 0; |
||||
|
||||
// dwTransferred is only set to nonzero if something has been read.
|
||||
// nError can be ERROR_SUCCESS or ERROR_HANDLE_EOF
|
||||
if(!SFileReadFile(hMpqFile, szBuffer, sizeof(szBuffer), &dwTransferred, NULL)) |
||||
nError = GetLastError(); |
||||
if(nError == ERROR_HANDLE_EOF) |
||||
nError = ERROR_SUCCESS; |
||||
if(dwTransferred == 0) |
||||
break; |
||||
|
||||
// If something has been actually read, write it
|
||||
if(!FileStream_Write(pLocalFile, NULL, szBuffer, dwTransferred)) |
||||
nError = GetLastError(); |
||||
} |
||||
|
||||
// Close the files
|
||||
if(hMpqFile != NULL) |
||||
SFileCloseFile(hMpqFile); |
||||
if(pLocalFile != NULL) |
||||
FileStream_Close(pLocalFile); |
||||
if(nError != ERROR_SUCCESS) |
||||
SetLastError(nError); |
||||
return (nError == ERROR_SUCCESS); |
||||
} |
||||
@ -0,0 +1,481 @@
|
||||
/*****************************************************************************/ |
||||
/* SFileFindFile.cpp Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* A module for file searching within MPQs */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 25.03.03 1.00 Lad The first version of SFileFindFile.cpp */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define __STORMLIB_SELF__ |
||||
#include "StormLib.h" |
||||
#include "StormCommon.h" |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Private structure used for file search (search handle)
|
||||
|
||||
// Used by searching in MPQ archives
|
||||
struct TMPQSearch |
||||
{ |
||||
TMPQArchive * ha; // Handle to MPQ, where the search runs
|
||||
TFileEntry ** pSearchTable; // Table for files that have been already found
|
||||
DWORD dwSearchTableItems; // Number of items in the search table
|
||||
DWORD dwNextIndex; // Next file index to be checked
|
||||
DWORD dwFlagMask; // For checking flag mask
|
||||
char szSearchMask[1]; // Search mask (variable length)
|
||||
}; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
static TMPQSearch * IsValidSearchHandle(HANDLE hFind) |
||||
{ |
||||
TMPQSearch * hs = (TMPQSearch *)hFind; |
||||
|
||||
if(hs != NULL && IsValidMpqHandle(hs->ha)) |
||||
return hs; |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
bool CheckWildCard(const char * szString, const char * szWildCard) |
||||
{ |
||||
const char * szWildCardPtr; |
||||
|
||||
for(;;) |
||||
{ |
||||
// If there is '?' in the wildcard, we skip one char
|
||||
while(szWildCard[0] == '?') |
||||
{ |
||||
if(szString[0] == 0) |
||||
return false; |
||||
|
||||
szWildCard++; |
||||
szString++; |
||||
} |
||||
|
||||
// Handle '*'
|
||||
szWildCardPtr = szWildCard; |
||||
if(szWildCardPtr[0] != 0) |
||||
{ |
||||
if(szWildCardPtr[0] == '*') |
||||
{ |
||||
szWildCardPtr++; |
||||
|
||||
if(szWildCardPtr[0] == '*') |
||||
continue; |
||||
|
||||
if(szWildCardPtr[0] == 0) |
||||
return true; |
||||
|
||||
if(AsciiToUpperTable[szWildCardPtr[0]] == AsciiToUpperTable[szString[0]]) |
||||
{ |
||||
if(CheckWildCard(szString, szWildCardPtr)) |
||||
return true; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if(AsciiToUpperTable[szWildCardPtr[0]] != AsciiToUpperTable[szString[0]]) |
||||
return false; |
||||
|
||||
szWildCard = szWildCardPtr + 1; |
||||
} |
||||
|
||||
if(szString[0] == 0) |
||||
return false; |
||||
szString++; |
||||
} |
||||
else |
||||
{ |
||||
return (szString[0] == 0) ? true : false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static DWORD GetSearchTableItems(TMPQArchive * ha) |
||||
{ |
||||
DWORD dwMergeItems = 0; |
||||
|
||||
// Loop over all patches
|
||||
while(ha != NULL) |
||||
{ |
||||
// Append the number of files
|
||||
dwMergeItems += (ha->pHetTable != NULL) ? ha->pHetTable->dwEntryCount |
||||
: ha->pHeader->dwBlockTableSize; |
||||
// Move to the patched archive
|
||||
ha = ha->haPatch; |
||||
} |
||||
|
||||
// Return the double size of number of items
|
||||
return (dwMergeItems | 1); |
||||
} |
||||
|
||||
static bool FileWasFoundBefore( |
||||
TMPQArchive * ha, |
||||
TMPQSearch * hs, |
||||
TFileEntry * pFileEntry) |
||||
{ |
||||
TFileEntry * pEntry; |
||||
char * szRealFileName = pFileEntry->szFileName; |
||||
DWORD dwStartIndex; |
||||
DWORD dwNameHash; |
||||
DWORD dwIndex; |
||||
|
||||
if(hs->pSearchTable != NULL && szRealFileName != NULL) |
||||
{ |
||||
// If we are in patch MPQ, we check if patch prefix matches
|
||||
// and then trim the patch prefix
|
||||
if(ha->pPatchPrefix != NULL) |
||||
{ |
||||
// If the patch prefix doesn't fit, we pretend that the file
|
||||
// was there before and it will be skipped
|
||||
if(_strnicmp(szRealFileName, ha->pPatchPrefix->szPatchPrefix, ha->pPatchPrefix->nLength)) |
||||
return true; |
||||
|
||||
szRealFileName += ha->pPatchPrefix->nLength; |
||||
} |
||||
|
||||
// Calculate the hash to the table
|
||||
dwNameHash = ha->pfnHashString(szRealFileName, MPQ_HASH_NAME_A); |
||||
dwStartIndex = dwIndex = (dwNameHash % hs->dwSearchTableItems); |
||||
|
||||
// The file might have been found before
|
||||
// only if this is not the first MPQ being searched
|
||||
if(ha->haBase != NULL) |
||||
{ |
||||
// Enumerate all entries in the search table
|
||||
for(;;) |
||||
{ |
||||
// Get the file entry at that position
|
||||
pEntry = hs->pSearchTable[dwIndex]; |
||||
if(pEntry == NULL) |
||||
break; |
||||
|
||||
if(pEntry->szFileName != NULL) |
||||
{ |
||||
// Does the name match?
|
||||
if(!_stricmp(pEntry->szFileName, szRealFileName)) |
||||
return true; |
||||
} |
||||
|
||||
// Move to the next entry
|
||||
dwIndex = (dwIndex + 1) % hs->dwSearchTableItems; |
||||
if(dwIndex == dwStartIndex) |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Put the entry to the table for later use
|
||||
hs->pSearchTable[dwIndex] = pFileEntry; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static TFileEntry * FindPatchEntry(TMPQArchive * ha, TFileEntry * pFileEntry) |
||||
{ |
||||
TFileEntry * pPatchEntry = pFileEntry; |
||||
TFileEntry * pTempEntry; |
||||
char szFileName[MAX_PATH+1]; |
||||
|
||||
// Can't find patch entry for a file that doesn't have name
|
||||
if(pFileEntry->szFileName != NULL && pFileEntry->szFileName[0] != 0) |
||||
{ |
||||
// Go while there are patches
|
||||
while(ha->haPatch != NULL) |
||||
{ |
||||
// Move to the patch archive
|
||||
ha = ha->haPatch; |
||||
szFileName[0] = 0; |
||||
|
||||
// Prepare the prefix for the file name
|
||||
if(ha->pPatchPrefix && ha->pPatchPrefix->nLength) |
||||
StringCopy(szFileName, _countof(szFileName), ha->pPatchPrefix->szPatchPrefix); |
||||
StringCat(szFileName, _countof(szFileName), pFileEntry->szFileName); |
||||
|
||||
// Try to find the file there
|
||||
pTempEntry = GetFileEntryExact(ha, szFileName, 0, NULL); |
||||
if(pTempEntry != NULL) |
||||
pPatchEntry = pTempEntry; |
||||
} |
||||
} |
||||
|
||||
// Return the found patch entry
|
||||
return pPatchEntry; |
||||
} |
||||
|
||||
static bool DoMPQSearch_FileEntry( |
||||
TMPQSearch * hs, |
||||
SFILE_FIND_DATA * lpFindFileData, |
||||
TMPQArchive * ha, |
||||
TMPQHash * pHashEntry, |
||||
TFileEntry * pFileEntry) |
||||
{ |
||||
TFileEntry * pPatchEntry; |
||||
HANDLE hFile = NULL; |
||||
const char * szFileName; |
||||
size_t nPrefixLength = (ha->pPatchPrefix != NULL) ? ha->pPatchPrefix->nLength : 0; |
||||
DWORD dwBlockIndex; |
||||
char szNameBuff[MAX_PATH]; |
||||
|
||||
// Is it a file but not a patch file?
|
||||
if((pFileEntry->dwFlags & hs->dwFlagMask) == MPQ_FILE_EXISTS) |
||||
{ |
||||
// Now we have to check if this file was not enumerated before
|
||||
if(!FileWasFoundBefore(ha, hs, pFileEntry)) |
||||
{ |
||||
// if(pFileEntry != NULL && !_stricmp(pFileEntry->szFileName, "TriggerLibs\\NativeLib.galaxy"))
|
||||
// DebugBreak();
|
||||
|
||||
// Find a patch to this file
|
||||
// Note: This either succeeds or returns pFileEntry
|
||||
pPatchEntry = FindPatchEntry(ha, pFileEntry); |
||||
|
||||
// Prepare the block index
|
||||
dwBlockIndex = (DWORD)(pFileEntry - ha->pFileTable); |
||||
|
||||
// Get the file name. If it's not known, we will create pseudo-name
|
||||
szFileName = pFileEntry->szFileName; |
||||
if(szFileName == NULL) |
||||
{ |
||||
// Open the file by its pseudo-name.
|
||||
sprintf(szNameBuff, "File%08u.xxx", (unsigned int)dwBlockIndex); |
||||
if(SFileOpenFileEx((HANDLE)hs->ha, szNameBuff, SFILE_OPEN_BASE_FILE, &hFile)) |
||||
{ |
||||
SFileGetFileName(hFile, szNameBuff); |
||||
szFileName = szNameBuff; |
||||
SFileCloseFile(hFile); |
||||
} |
||||
} |
||||
|
||||
// If the file name is still NULL, we cannot include the file to search results
|
||||
if(szFileName != NULL) |
||||
{ |
||||
// Check the file name against the wildcard
|
||||
if(CheckWildCard(szFileName + nPrefixLength, hs->szSearchMask)) |
||||
{ |
||||
// Fill the found entry. hash entry and block index are taken from the base MPQ
|
||||
lpFindFileData->dwHashIndex = HASH_ENTRY_FREE; |
||||
lpFindFileData->dwBlockIndex = dwBlockIndex; |
||||
lpFindFileData->dwFileSize = pPatchEntry->dwFileSize; |
||||
lpFindFileData->dwFileFlags = pPatchEntry->dwFlags; |
||||
lpFindFileData->dwCompSize = pPatchEntry->dwCmpSize; |
||||
lpFindFileData->lcLocale = 0; // pPatchEntry->lcLocale;
|
||||
|
||||
// Fill the filetime
|
||||
lpFindFileData->dwFileTimeHi = (DWORD)(pPatchEntry->FileTime >> 32); |
||||
lpFindFileData->dwFileTimeLo = (DWORD)(pPatchEntry->FileTime); |
||||
|
||||
// Fill-in the entries from hash table entry, if given
|
||||
if(pHashEntry != NULL) |
||||
{ |
||||
lpFindFileData->dwHashIndex = (DWORD)(pHashEntry - ha->pHashTable); |
||||
lpFindFileData->lcLocale = pHashEntry->lcLocale; |
||||
} |
||||
|
||||
// Fill the file name and plain file name
|
||||
StringCopy(lpFindFileData->cFileName, _countof(lpFindFileData->cFileName), szFileName + nPrefixLength); |
||||
lpFindFileData->szPlainName = (char *)GetPlainFileName(lpFindFileData->cFileName); |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Either not a valid item or was found before
|
||||
return false; |
||||
} |
||||
|
||||
static int DoMPQSearch_HashTable(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha) |
||||
{ |
||||
TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; |
||||
TMPQHash * pHash; |
||||
|
||||
// Parse the file table
|
||||
for(pHash = ha->pHashTable + hs->dwNextIndex; pHash < pHashTableEnd; pHash++) |
||||
{ |
||||
// Increment the next index for subsequent search
|
||||
hs->dwNextIndex++; |
||||
|
||||
// Does this hash table entry point to a proper block table entry?
|
||||
if(IsValidHashEntry(ha, pHash)) |
||||
{ |
||||
// Check if this file entry should be included in the search result
|
||||
if(DoMPQSearch_FileEntry(hs, lpFindFileData, ha, pHash, ha->pFileTable + MPQ_BLOCK_INDEX(pHash))) |
||||
return ERROR_SUCCESS; |
||||
} |
||||
} |
||||
|
||||
// No more files
|
||||
return ERROR_NO_MORE_FILES; |
||||
} |
||||
|
||||
static int DoMPQSearch_FileTable(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData, TMPQArchive * ha) |
||||
{ |
||||
TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; |
||||
TFileEntry * pFileEntry; |
||||
|
||||
// Parse the file table
|
||||
for(pFileEntry = ha->pFileTable + hs->dwNextIndex; pFileEntry < pFileTableEnd; pFileEntry++) |
||||
{ |
||||
// Increment the next index for subsequent search
|
||||
hs->dwNextIndex++; |
||||
|
||||
// Check if this file entry should be included in the search result
|
||||
if(DoMPQSearch_FileEntry(hs, lpFindFileData, ha, NULL, pFileEntry)) |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
// No more files
|
||||
return ERROR_NO_MORE_FILES; |
||||
} |
||||
|
||||
// Performs one MPQ search
|
||||
static int DoMPQSearch(TMPQSearch * hs, SFILE_FIND_DATA * lpFindFileData) |
||||
{ |
||||
TMPQArchive * ha = hs->ha; |
||||
int nError; |
||||
|
||||
// Start searching with base MPQ
|
||||
while(ha != NULL) |
||||
{ |
||||
// If the archive has hash table, we need to use hash table
|
||||
// in order to catch hash table index and file locale.
|
||||
// Note: If multiple hash table entries, point to the same block entry,
|
||||
// we need, to report them all
|
||||
nError = (ha->pHashTable != NULL) ? DoMPQSearch_HashTable(hs, lpFindFileData, ha) |
||||
: DoMPQSearch_FileTable(hs, lpFindFileData, ha); |
||||
if(nError == ERROR_SUCCESS) |
||||
return nError; |
||||
|
||||
// If there is no more patches in the chain, stop it.
|
||||
// This also keeps hs->ha non-NULL, which is required
|
||||
// for freeing the handle later
|
||||
if(ha->haPatch == NULL) |
||||
break; |
||||
|
||||
// Move to the next patch in the patch chain
|
||||
hs->ha = ha = ha->haPatch; |
||||
hs->dwNextIndex = 0; |
||||
} |
||||
|
||||
// No more files found, return error
|
||||
return ERROR_NO_MORE_FILES; |
||||
} |
||||
|
||||
static void FreeMPQSearch(TMPQSearch *& hs) |
||||
{ |
||||
if(hs != NULL) |
||||
{ |
||||
if(hs->pSearchTable != NULL) |
||||
STORM_FREE(hs->pSearchTable); |
||||
STORM_FREE(hs); |
||||
hs = NULL; |
||||
} |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Public functions
|
||||
|
||||
HANDLE WINAPI SFileFindFirstFile(HANDLE hMpq, const char * szMask, SFILE_FIND_DATA * lpFindFileData, const TCHAR * szListFile) |
||||
{ |
||||
TMPQArchive * ha = (TMPQArchive *)hMpq; |
||||
TMPQSearch * hs = NULL; |
||||
size_t nSize = 0; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Check for the valid parameters
|
||||
if(!IsValidMpqHandle(hMpq)) |
||||
nError = ERROR_INVALID_HANDLE; |
||||
if(szMask == NULL || lpFindFileData == NULL) |
||||
nError = ERROR_INVALID_PARAMETER; |
||||
|
||||
#ifdef FULL |
||||
// Include the listfile into the MPQ's internal listfile
|
||||
// Note that if the listfile name is NULL, do nothing because the
|
||||
// internal listfile is always included.
|
||||
if(nError == ERROR_SUCCESS && szListFile != NULL && *szListFile != 0) |
||||
nError = SFileAddListFile((HANDLE)ha, szListFile); |
||||
#endif |
||||
|
||||
// Allocate the structure for MPQ search
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
nSize = sizeof(TMPQSearch) + strlen(szMask) + 1; |
||||
if((hs = (TMPQSearch *)STORM_ALLOC(char, nSize)) == NULL) |
||||
nError = ERROR_NOT_ENOUGH_MEMORY; |
||||
} |
||||
|
||||
// Perform the first search
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
memset(hs, 0, sizeof(TMPQSearch)); |
||||
strcpy(hs->szSearchMask, szMask); |
||||
hs->dwFlagMask = MPQ_FILE_EXISTS; |
||||
hs->ha = ha; |
||||
|
||||
// If the archive is patched archive, we have to create a merge table
|
||||
// to prevent files being repeated
|
||||
if(ha->haPatch != NULL) |
||||
{ |
||||
hs->dwSearchTableItems = GetSearchTableItems(ha); |
||||
hs->pSearchTable = STORM_ALLOC(TFileEntry *, hs->dwSearchTableItems); |
||||
hs->dwFlagMask = MPQ_FILE_EXISTS | MPQ_FILE_PATCH_FILE; |
||||
if(hs->pSearchTable != NULL) |
||||
memset(hs->pSearchTable, 0, hs->dwSearchTableItems * sizeof(TFileEntry *)); |
||||
else |
||||
nError = ERROR_NOT_ENOUGH_MEMORY; |
||||
} |
||||
} |
||||
|
||||
// Perform first item searching
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
nError = DoMPQSearch(hs, lpFindFileData); |
||||
} |
||||
|
||||
// Cleanup
|
||||
if(nError != ERROR_SUCCESS) |
||||
{ |
||||
FreeMPQSearch(hs); |
||||
SetLastError(nError); |
||||
} |
||||
|
||||
// Return the result value
|
||||
return (HANDLE)hs; |
||||
} |
||||
|
||||
bool WINAPI SFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData) |
||||
{ |
||||
TMPQSearch * hs = IsValidSearchHandle(hFind); |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Check the parameters
|
||||
if(hs == NULL) |
||||
nError = ERROR_INVALID_HANDLE; |
||||
if(lpFindFileData == NULL) |
||||
nError = ERROR_INVALID_PARAMETER; |
||||
|
||||
if(nError == ERROR_SUCCESS) |
||||
nError = DoMPQSearch(hs, lpFindFileData); |
||||
|
||||
if(nError != ERROR_SUCCESS) |
||||
SetLastError(nError); |
||||
return (nError == ERROR_SUCCESS); |
||||
} |
||||
|
||||
bool WINAPI SFileFindClose(HANDLE hFind) |
||||
{ |
||||
TMPQSearch * hs = IsValidSearchHandle(hFind); |
||||
|
||||
// Check the parameters
|
||||
if(hs == NULL) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return false; |
||||
} |
||||
|
||||
FreeMPQSearch(hs); |
||||
return true; |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,618 @@
|
||||
/*****************************************************************************/ |
||||
/* SFileOpenArchive.cpp Copyright Ladislav Zezula 1999 */ |
||||
/* */ |
||||
/* Author : Ladislav Zezula */ |
||||
/* E-mail : ladik@zezula.net */ |
||||
/* WWW : www.zezula.net */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Archive functions of Storm.dll */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* xx.xx.xx 1.00 Lad The first version of SFileOpenArchive.cpp */ |
||||
/* 19.11.03 1.01 Dan Big endian handling */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define __STORMLIB_SELF__ |
||||
#include "StormLib.h" |
||||
#include "StormCommon.h" |
||||
|
||||
#define HEADER_SEARCH_BUFFER_SIZE 0x1000 |
||||
|
||||
/*****************************************************************************/ |
||||
/* Local functions */ |
||||
/*****************************************************************************/ |
||||
|
||||
static bool IsAviFile(DWORD * HeaderData) |
||||
{ |
||||
DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]); |
||||
DWORD DwordValue2 = BSWAP_INT32_UNSIGNED(HeaderData[2]); |
||||
DWORD DwordValue3 = BSWAP_INT32_UNSIGNED(HeaderData[3]); |
||||
|
||||
// Test for 'RIFF', 'AVI ' or 'LIST'
|
||||
return (DwordValue0 == 0x46464952 && DwordValue2 == 0x20495641 && DwordValue3 == 0x5453494C); |
||||
} |
||||
|
||||
static bool IsWarcraft3Map(DWORD * HeaderData) |
||||
{ |
||||
DWORD DwordValue0 = BSWAP_INT32_UNSIGNED(HeaderData[0]); |
||||
DWORD DwordValue1 = BSWAP_INT32_UNSIGNED(HeaderData[1]); |
||||
|
||||
return (DwordValue0 == 0x57334D48 && DwordValue1 == 0x00000000); |
||||
} |
||||
|
||||
static TMPQUserData * IsValidMpqUserData(ULONGLONG ByteOffset, ULONGLONG FileSize, void * pvUserData) |
||||
{ |
||||
TMPQUserData * pUserData; |
||||
|
||||
// BSWAP the source data and copy them to our buffer
|
||||
BSWAP_ARRAY32_UNSIGNED(&pvUserData, sizeof(TMPQUserData)); |
||||
pUserData = (TMPQUserData *)pvUserData; |
||||
|
||||
// Check the sizes
|
||||
if(pUserData->cbUserDataHeader <= pUserData->cbUserDataSize && pUserData->cbUserDataSize <= pUserData->dwHeaderOffs) |
||||
{ |
||||
// Move to the position given by the userdata
|
||||
ByteOffset += pUserData->dwHeaderOffs; |
||||
|
||||
// The MPQ header should be within range of the file size
|
||||
if((ByteOffset + MPQ_HEADER_SIZE_V1) < FileSize) |
||||
{ |
||||
// Note: We should verify if there is the MPQ header.
|
||||
// However, the header could be at any position below that
|
||||
// that is multiplier of 0x200
|
||||
return (TMPQUserData *)pvUserData; |
||||
} |
||||
} |
||||
|
||||
return NULL; |
||||
} |
||||
|
||||
// This function gets the right positions of the hash table and the block table.
|
||||
static int VerifyMpqTablePositions(TMPQArchive * ha, ULONGLONG FileSize) |
||||
{ |
||||
TMPQHeader * pHeader = ha->pHeader; |
||||
ULONGLONG ByteOffset; |
||||
|
||||
// Check the begin of HET table
|
||||
if(pHeader->HetTablePos64) |
||||
{ |
||||
ByteOffset = ha->MpqPos + pHeader->HetTablePos64; |
||||
if(ByteOffset > FileSize) |
||||
return ERROR_BAD_FORMAT; |
||||
} |
||||
|
||||
// Check the begin of BET table
|
||||
if(pHeader->BetTablePos64) |
||||
{ |
||||
ByteOffset = ha->MpqPos + pHeader->BetTablePos64; |
||||
if(ByteOffset > FileSize) |
||||
return ERROR_BAD_FORMAT; |
||||
} |
||||
|
||||
// Check the begin of hash table
|
||||
if(pHeader->wHashTablePosHi || pHeader->dwHashTablePos) |
||||
{ |
||||
ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wHashTablePosHi, pHeader->dwHashTablePos)); |
||||
if(ByteOffset > FileSize) |
||||
return ERROR_BAD_FORMAT; |
||||
} |
||||
|
||||
// Check the begin of block table
|
||||
if(pHeader->wBlockTablePosHi || pHeader->dwBlockTablePos) |
||||
{ |
||||
ByteOffset = FileOffsetFromMpqOffset(ha, MAKE_OFFSET64(pHeader->wBlockTablePosHi, pHeader->dwBlockTablePos)); |
||||
if(ByteOffset > FileSize) |
||||
return ERROR_BAD_FORMAT; |
||||
} |
||||
|
||||
// Check the begin of hi-block table
|
||||
if(pHeader->HiBlockTablePos64 != 0) |
||||
{ |
||||
ByteOffset = ha->MpqPos + pHeader->HiBlockTablePos64; |
||||
if(ByteOffset > FileSize) |
||||
return ERROR_BAD_FORMAT; |
||||
} |
||||
|
||||
// All OK.
|
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
|
||||
/*****************************************************************************/ |
||||
/* Public functions */ |
||||
/*****************************************************************************/ |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileGetLocale and SFileSetLocale
|
||||
// Set the locale for all newly opened files
|
||||
|
||||
LCID WINAPI SFileGetLocale() |
||||
{ |
||||
return lcFileLocale; |
||||
} |
||||
|
||||
LCID WINAPI SFileSetLocale(LCID lcNewLocale) |
||||
{ |
||||
lcFileLocale = lcNewLocale; |
||||
return lcFileLocale; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileOpenArchive
|
||||
//
|
||||
// szFileName - MPQ archive file name to open
|
||||
// dwPriority - When SFileOpenFileEx called, this contains the search priority for searched archives
|
||||
// dwFlags - See MPQ_OPEN_XXX in StormLib.h
|
||||
// phMpq - Pointer to store open archive handle
|
||||
|
||||
bool WINAPI SFileOpenArchive( |
||||
const TCHAR * szMpqName, |
||||
DWORD dwPriority, |
||||
DWORD dwFlags, |
||||
HANDLE * phMpq) |
||||
{ |
||||
TMPQUserData * pUserData; |
||||
TFileStream * pStream = NULL; // Open file stream
|
||||
TMPQArchive * ha = NULL; // Archive handle
|
||||
TFileEntry * pFileEntry; |
||||
ULONGLONG FileSize = 0; // Size of the file
|
||||
LPBYTE pbHeaderBuffer = NULL; // Buffer for searching MPQ header
|
||||
DWORD dwStreamFlags = (dwFlags & STREAM_FLAGS_MASK); |
||||
bool bIsWarcraft3Map = false; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Verify the parameters
|
||||
if(szMpqName == NULL || *szMpqName == 0 || phMpq == NULL) |
||||
{ |
||||
SetLastError(ERROR_INVALID_PARAMETER); |
||||
return false; |
||||
} |
||||
|
||||
// One time initialization of MPQ cryptography
|
||||
InitializeMpqCryptography(); |
||||
dwPriority = dwPriority; |
||||
|
||||
// If not forcing MPQ v 1.0, also use file bitmap
|
||||
dwStreamFlags |= (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) ? 0 : STREAM_FLAG_USE_BITMAP; |
||||
|
||||
#ifndef FULL |
||||
char translatedName[260]; |
||||
TranslateFileName(translatedName, sizeof(translatedName), szMpqName); |
||||
#endif |
||||
|
||||
// Open the MPQ archive file
|
||||
pStream = FileStream_OpenFile(translatedName, dwStreamFlags); |
||||
if(pStream == NULL) |
||||
return false; |
||||
|
||||
// Check the file size. There must be at least 0x20 bytes
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
FileStream_GetSize(pStream, &FileSize); |
||||
if(FileSize < MPQ_HEADER_SIZE_V1) |
||||
nError = ERROR_BAD_FORMAT; |
||||
} |
||||
|
||||
// Allocate the MPQhandle
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
if((ha = STORM_ALLOC(TMPQArchive, 1)) == NULL) |
||||
nError = ERROR_NOT_ENOUGH_MEMORY; |
||||
} |
||||
|
||||
// Allocate buffer for searching MPQ header
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
pbHeaderBuffer = STORM_ALLOC(BYTE, HEADER_SEARCH_BUFFER_SIZE); |
||||
if(pbHeaderBuffer == NULL) |
||||
nError = ERROR_NOT_ENOUGH_MEMORY; |
||||
} |
||||
|
||||
// Find the position of MPQ header
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
ULONGLONG SearchOffset = 0; |
||||
ULONGLONG EndOfSearch = FileSize; |
||||
DWORD dwStrmFlags = 0; |
||||
DWORD dwHeaderSize; |
||||
DWORD dwHeaderID; |
||||
bool bSearchComplete = false; |
||||
|
||||
memset(ha, 0, sizeof(TMPQArchive)); |
||||
ha->pfnHashString = HashStringSlash; |
||||
ha->pStream = pStream; |
||||
pStream = NULL; |
||||
|
||||
// Set the archive read only if the stream is read-only
|
||||
FileStream_GetFlags(ha->pStream, &dwStrmFlags); |
||||
ha->dwFlags |= (dwStrmFlags & STREAM_FLAG_READ_ONLY) ? MPQ_FLAG_READ_ONLY : 0; |
||||
|
||||
// Also remember if we shall check sector CRCs when reading file
|
||||
ha->dwFlags |= (dwFlags & MPQ_OPEN_CHECK_SECTOR_CRC) ? MPQ_FLAG_CHECK_SECTOR_CRC : 0; |
||||
|
||||
// Also remember if this MPQ is a patch
|
||||
ha->dwFlags |= (dwFlags & MPQ_OPEN_PATCH) ? MPQ_FLAG_PATCH : 0; |
||||
|
||||
// Limit the header searching to about 130 MB of data
|
||||
if(EndOfSearch > 0x08000000) |
||||
EndOfSearch = 0x08000000; |
||||
|
||||
// Find the offset of MPQ header within the file
|
||||
while(bSearchComplete == false && SearchOffset < EndOfSearch) |
||||
{ |
||||
// Always read at least 0x1000 bytes for performance.
|
||||
// This is what Storm.dll (2002) does.
|
||||
DWORD dwBytesAvailable = HEADER_SEARCH_BUFFER_SIZE; |
||||
DWORD dwInBufferOffset = 0; |
||||
|
||||
// Cut the bytes available, if needed
|
||||
if((FileSize - SearchOffset) < HEADER_SEARCH_BUFFER_SIZE) |
||||
dwBytesAvailable = (DWORD)(FileSize - SearchOffset); |
||||
|
||||
// Read the eventual MPQ header
|
||||
if(!FileStream_Read(ha->pStream, &SearchOffset, pbHeaderBuffer, dwBytesAvailable)) |
||||
{ |
||||
nError = GetLastError(); |
||||
break; |
||||
} |
||||
|
||||
// There are AVI files from Warcraft III with 'MPQ' extension.
|
||||
if(SearchOffset == 0) |
||||
{ |
||||
if(IsAviFile((DWORD *)pbHeaderBuffer)) |
||||
{ |
||||
nError = ERROR_AVI_FILE; |
||||
break; |
||||
} |
||||
|
||||
bIsWarcraft3Map = IsWarcraft3Map((DWORD *)pbHeaderBuffer); |
||||
} |
||||
|
||||
// Search the header buffer
|
||||
while(dwInBufferOffset < dwBytesAvailable) |
||||
{ |
||||
// Copy the data from the potential header buffer to the MPQ header
|
||||
memcpy(ha->HeaderData, pbHeaderBuffer + dwInBufferOffset, sizeof(ha->HeaderData)); |
||||
|
||||
// If there is the MPQ user data, process it
|
||||
// Note that Warcraft III does not check for user data, which is abused by many map protectors
|
||||
dwHeaderID = BSWAP_INT32_UNSIGNED(ha->HeaderData[0]); |
||||
if(bIsWarcraft3Map == false && (dwFlags & MPQ_OPEN_FORCE_MPQ_V1) == 0) |
||||
{ |
||||
if(ha->pUserData == NULL && dwHeaderID == ID_MPQ_USERDATA) |
||||
{ |
||||
// Verify if this looks like a valid user data
|
||||
pUserData = IsValidMpqUserData(SearchOffset, FileSize, ha->HeaderData); |
||||
if(pUserData != NULL) |
||||
{ |
||||
// Fill the user data header
|
||||
ha->UserDataPos = SearchOffset; |
||||
ha->pUserData = &ha->UserData; |
||||
memcpy(ha->pUserData, pUserData, sizeof(TMPQUserData)); |
||||
|
||||
// Continue searching from that position
|
||||
SearchOffset += ha->pUserData->dwHeaderOffs; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// There must be MPQ header signature. Note that STORM.dll from Warcraft III actually
|
||||
// tests the MPQ header size. It must be at least 0x20 bytes in order to load it
|
||||
// Abused by Spazzler Map protector. Note that the size check is not present
|
||||
// in Storm.dll v 1.00, so Diablo I code would load the MPQ anyway.
|
||||
dwHeaderSize = BSWAP_INT32_UNSIGNED(ha->HeaderData[1]); |
||||
if(dwHeaderID == ID_MPQ && dwHeaderSize >= MPQ_HEADER_SIZE_V1) |
||||
{ |
||||
// Now convert the header to version 4
|
||||
nError = ConvertMpqHeaderToFormat4(ha, SearchOffset, FileSize, dwFlags, bIsWarcraft3Map); |
||||
bSearchComplete = true; |
||||
break; |
||||
} |
||||
|
||||
// Check for MPK archives (Longwu Online - MPQ fork)
|
||||
if(bIsWarcraft3Map == false && dwHeaderID == ID_MPK) |
||||
{ |
||||
// Now convert the MPK header to MPQ Header version 4
|
||||
nError = ConvertMpkHeaderToFormat4(ha, FileSize, dwFlags); |
||||
bSearchComplete = true; |
||||
break; |
||||
} |
||||
|
||||
// If searching for the MPQ header is disabled, return an error
|
||||
if(dwFlags & MPQ_OPEN_NO_HEADER_SEARCH) |
||||
{ |
||||
nError = ERROR_NOT_SUPPORTED; |
||||
bSearchComplete = true; |
||||
break; |
||||
} |
||||
|
||||
// Move the pointers
|
||||
SearchOffset += 0x200; |
||||
dwInBufferOffset += 0x200; |
||||
} |
||||
} |
||||
|
||||
// Did we identify one of the supported headers?
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
// Set the user data position to the MPQ header, if none
|
||||
if(ha->pUserData == NULL) |
||||
ha->UserDataPos = SearchOffset; |
||||
|
||||
// Set the position of the MPQ header
|
||||
ha->pHeader = (TMPQHeader *)ha->HeaderData; |
||||
ha->MpqPos = SearchOffset; |
||||
ha->FileSize = FileSize; |
||||
|
||||
// Sector size must be nonzero.
|
||||
if(SearchOffset >= FileSize || ha->pHeader->wSectorSize == 0) |
||||
nError = ERROR_BAD_FORMAT; |
||||
} |
||||
} |
||||
|
||||
// Fix table positions according to format
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
// Dump the header
|
||||
// DumpMpqHeader(ha->pHeader);
|
||||
|
||||
// W3x Map Protectors use the fact that War3's Storm.dll ignores the MPQ user data,
|
||||
// and ignores the MPQ format version as well. The trick is to
|
||||
// fake MPQ format 2, with an improper hi-word position of hash table and block table
|
||||
// We can overcome such protectors by forcing opening the archive as MPQ v 1.0
|
||||
if(dwFlags & MPQ_OPEN_FORCE_MPQ_V1) |
||||
{ |
||||
ha->pHeader->wFormatVersion = MPQ_FORMAT_VERSION_1; |
||||
ha->pHeader->dwHeaderSize = MPQ_HEADER_SIZE_V1; |
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY; |
||||
ha->pUserData = NULL; |
||||
} |
||||
|
||||
// Anti-overflow. If the hash table size in the header is
|
||||
// higher than 0x10000000, it would overflow in 32-bit version
|
||||
// Observed in the malformed Warcraft III maps
|
||||
// Example map: MPQ_2016_v1_ProtectedMap_TableSizeOverflow.w3x
|
||||
ha->pHeader->dwBlockTableSize = (ha->pHeader->dwBlockTableSize & BLOCK_INDEX_MASK); |
||||
ha->pHeader->dwHashTableSize = (ha->pHeader->dwHashTableSize & BLOCK_INDEX_MASK); |
||||
|
||||
// Both MPQ_OPEN_NO_LISTFILE or MPQ_OPEN_NO_ATTRIBUTES trigger read only mode
|
||||
if(dwFlags & (MPQ_OPEN_NO_LISTFILE | MPQ_OPEN_NO_ATTRIBUTES)) |
||||
ha->dwFlags |= MPQ_FLAG_READ_ONLY; |
||||
|
||||
// Remember whether whis is a map for Warcraft III
|
||||
if(bIsWarcraft3Map) |
||||
ha->dwFlags |= MPQ_FLAG_WAR3_MAP; |
||||
|
||||
// Set the size of file sector
|
||||
ha->dwSectorSize = (0x200 << ha->pHeader->wSectorSize); |
||||
|
||||
// Verify if any of the tables doesn't start beyond the end of the file
|
||||
nError = VerifyMpqTablePositions(ha, FileSize); |
||||
} |
||||
|
||||
// Read the hash table. Ignore the result, as hash table is no longer required
|
||||
// Read HET table. Ignore the result, as HET table is no longer required
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
nError = LoadAnyHashTable(ha); |
||||
} |
||||
|
||||
// Now, build the file table. It will be built by combining
|
||||
// the block table, BET table, hi-block table, (attributes) and (listfile).
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
nError = BuildFileTable(ha); |
||||
} |
||||
|
||||
#ifdef FULL |
||||
// Load the internal listfile and include it to the file table
|
||||
if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_LISTFILE) == 0) |
||||
{ |
||||
// Quick check for (listfile)
|
||||
pFileEntry = GetFileEntryLocale(ha, LISTFILE_NAME, LANG_NEUTRAL); |
||||
if(pFileEntry != NULL) |
||||
{ |
||||
// Ignore result of the operation. (listfile) is optional.
|
||||
SFileAddListFile((HANDLE)ha, NULL); |
||||
ha->dwFileFlags1 = pFileEntry->dwFlags; |
||||
} |
||||
} |
||||
|
||||
// Load the "(attributes)" file and merge it to the file table
|
||||
if(nError == ERROR_SUCCESS && (dwFlags & MPQ_OPEN_NO_ATTRIBUTES) == 0 && (ha->dwFlags & MPQ_FLAG_BLOCK_TABLE_CUT) == 0) |
||||
{ |
||||
// Quick check for (attributes)
|
||||
pFileEntry = GetFileEntryLocale(ha, ATTRIBUTES_NAME, LANG_NEUTRAL); |
||||
if(pFileEntry != NULL) |
||||
{ |
||||
// Ignore result of the operation. (attributes) is optional.
|
||||
SAttrLoadAttributes(ha); |
||||
ha->dwFileFlags2 = pFileEntry->dwFlags; |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
// Remember whether the archive has weak signature. Only for MPQs format 1.0.
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
// Quick check for (signature)
|
||||
pFileEntry = GetFileEntryLocale(ha, SIGNATURE_NAME, LANG_NEUTRAL); |
||||
if(pFileEntry != NULL) |
||||
{ |
||||
// Just remember that the archive is weak-signed
|
||||
assert((pFileEntry->dwFlags & MPQ_FILE_EXISTS) != 0); |
||||
ha->dwFileFlags3 = pFileEntry->dwFlags; |
||||
} |
||||
|
||||
// Finally, set the MPQ_FLAG_READ_ONLY if the MPQ was found malformed
|
||||
ha->dwFlags |= (ha->dwFlags & MPQ_FLAG_MALFORMED) ? MPQ_FLAG_READ_ONLY : 0; |
||||
} |
||||
|
||||
// Cleanup and exit
|
||||
if(nError != ERROR_SUCCESS) |
||||
{ |
||||
FileStream_Close(pStream); |
||||
FreeArchiveHandle(ha); |
||||
SetLastError(nError); |
||||
ha = NULL; |
||||
} |
||||
|
||||
// Free the header buffer
|
||||
if(pbHeaderBuffer != NULL) |
||||
STORM_FREE(pbHeaderBuffer); |
||||
if(phMpq != NULL) |
||||
*phMpq = ha; |
||||
return (nError == ERROR_SUCCESS); |
||||
} |
||||
|
||||
|
||||
#ifdef FULL |
||||
//-----------------------------------------------------------------------------
|
||||
// bool WINAPI SFileSetDownloadCallback(HANDLE, SFILE_DOWNLOAD_CALLBACK, void *);
|
||||
//
|
||||
// Sets a callback that is called when content is downloaded from the master MPQ
|
||||
//
|
||||
|
||||
bool WINAPI SFileSetDownloadCallback(HANDLE hMpq, SFILE_DOWNLOAD_CALLBACK DownloadCB, void * pvUserData) |
||||
{ |
||||
TMPQArchive * ha = (TMPQArchive *)hMpq; |
||||
|
||||
// Do nothing if 'hMpq' is bad parameter
|
||||
if(!IsValidMpqHandle(hMpq)) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return false; |
||||
} |
||||
|
||||
return FileStream_SetCallback(ha->pStream, DownloadCB, pvUserData); |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool SFileFlushArchive(HANDLE hMpq)
|
||||
//
|
||||
// Saves all dirty data into MPQ archive.
|
||||
// Has similar effect like SFileCloseArchive, but the archive is not closed.
|
||||
// Use on clients who keep MPQ archive open even for write operations,
|
||||
// and terminating without calling SFileCloseArchive might corrupt the archive.
|
||||
//
|
||||
|
||||
bool WINAPI SFileFlushArchive(HANDLE hMpq) |
||||
{ |
||||
TMPQArchive * ha; |
||||
int nResultError = ERROR_SUCCESS; |
||||
int nError; |
||||
|
||||
// Do nothing if 'hMpq' is bad parameter
|
||||
if((ha = IsValidMpqHandle(hMpq)) == NULL) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return false; |
||||
} |
||||
|
||||
// Only if the MPQ was changed
|
||||
if(ha->dwFlags & MPQ_FLAG_CHANGED) |
||||
{ |
||||
// Indicate that we are saving MPQ internal structures
|
||||
ha->dwFlags |= MPQ_FLAG_SAVING_TABLES; |
||||
|
||||
// Defragment the file table. This will allow us to put the internal files to the end
|
||||
DefragmentFileTable(ha); |
||||
|
||||
//
|
||||
// Create each internal file
|
||||
// Note that the (signature) file is usually before (listfile) in the file table
|
||||
//
|
||||
|
||||
if(ha->dwFlags & MPQ_FLAG_SIGNATURE_NEW) |
||||
{ |
||||
#ifdef FULL |
||||
nError = SSignFileCreate(ha); |
||||
if(nError != ERROR_SUCCESS) |
||||
nResultError = nError; |
||||
#else |
||||
assert(0); |
||||
#endif |
||||
} |
||||
|
||||
if(ha->dwFlags & MPQ_FLAG_LISTFILE_NEW) |
||||
{ |
||||
nError = SListFileSaveToMpq(ha); |
||||
if(nError != ERROR_SUCCESS) |
||||
nResultError = nError; |
||||
} |
||||
|
||||
if(ha->dwFlags & MPQ_FLAG_ATTRIBUTES_NEW) |
||||
{ |
||||
nError = SAttrFileSaveToMpq(ha); |
||||
if(nError != ERROR_SUCCESS) |
||||
nResultError = nError; |
||||
} |
||||
|
||||
// Save HET table, BET table, hash table, block table, hi-block table
|
||||
if(ha->dwFlags & MPQ_FLAG_CHANGED) |
||||
{ |
||||
// Rebuild the HET table
|
||||
if(ha->pHetTable != NULL) |
||||
RebuildHetTable(ha); |
||||
|
||||
// Save all MPQ tables first
|
||||
nError = SaveMPQTables(ha); |
||||
if(nError != ERROR_SUCCESS) |
||||
nResultError = nError; |
||||
|
||||
// If the archive has weak signature, we need to finish it
|
||||
if(ha->dwFileFlags3 != 0) |
||||
{ |
||||
#ifdef FULL |
||||
nError = SSignFileFinish(ha); |
||||
if(nError != ERROR_SUCCESS) |
||||
nResultError = nError; |
||||
#else |
||||
assert(0); |
||||
#endif |
||||
} |
||||
} |
||||
|
||||
// We are no longer saving internal MPQ structures
|
||||
ha->dwFlags &= ~MPQ_FLAG_SAVING_TABLES; |
||||
} |
||||
|
||||
// Return the error
|
||||
if(nResultError != ERROR_SUCCESS) |
||||
SetLastError(nResultError); |
||||
return (nResultError == ERROR_SUCCESS); |
||||
} |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool SFileCloseArchive(HANDLE hMpq);
|
||||
//
|
||||
|
||||
bool WINAPI SFileCloseArchive(HANDLE hMpq) |
||||
{ |
||||
TMPQArchive * ha = IsValidMpqHandle(hMpq); |
||||
bool bResult = true; |
||||
|
||||
// Only if the handle is valid
|
||||
if(ha == NULL) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return false; |
||||
} |
||||
|
||||
// Invalidate the add file callback so it won't be called
|
||||
// when saving (listfile) and (attributes)
|
||||
ha->pfnAddFileCB = NULL; |
||||
ha->pvAddFileUserData = NULL; |
||||
|
||||
#ifdef FULL |
||||
// Flush all unsaved data to the storage
|
||||
bResult = SFileFlushArchive(hMpq); |
||||
#endif |
||||
|
||||
// Free all memory used by MPQ archive
|
||||
FreeArchiveHandle(ha); |
||||
return bResult; |
||||
} |
||||
@ -0,0 +1,398 @@
|
||||
/*****************************************************************************/ |
||||
/* SFileOpenFileEx.cpp Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Description : */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* xx.xx.99 1.00 Lad The first version of SFileOpenFileEx.cpp */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define __STORMLIB_SELF__ |
||||
#include "StormLib.h" |
||||
#include "StormCommon.h" |
||||
|
||||
/*****************************************************************************/ |
||||
/* Local functions */ |
||||
/*****************************************************************************/ |
||||
|
||||
static DWORD FindHashIndex(TMPQArchive * ha, DWORD dwFileIndex) |
||||
{ |
||||
TMPQHash * pHashTableEnd; |
||||
TMPQHash * pHash; |
||||
DWORD dwFirstIndex = HASH_ENTRY_FREE; |
||||
|
||||
// Should only be called if the archive has hash table
|
||||
assert(ha->pHashTable != NULL); |
||||
|
||||
// Multiple hash table entries can point to the file table entry.
|
||||
// We need to search all of them
|
||||
pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; |
||||
for(pHash = ha->pHashTable; pHash < pHashTableEnd; pHash++) |
||||
{ |
||||
if(MPQ_BLOCK_INDEX(pHash) == dwFileIndex) |
||||
{ |
||||
// Duplicate hash entry found
|
||||
if(dwFirstIndex != HASH_ENTRY_FREE) |
||||
return HASH_ENTRY_FREE; |
||||
dwFirstIndex = (DWORD)(pHash - ha->pHashTable); |
||||
} |
||||
} |
||||
|
||||
// Return the hash table entry index
|
||||
return dwFirstIndex; |
||||
} |
||||
|
||||
static const char * GetPatchFileName(TMPQArchive * ha, const char * szFileName, char * szBuffer) |
||||
{ |
||||
TMPQNamePrefix * pPrefix; |
||||
|
||||
// Are there patches in the current MPQ?
|
||||
if(ha->dwFlags & MPQ_FLAG_PATCH) |
||||
{ |
||||
// The patch prefix must be already known here
|
||||
assert(ha->pPatchPrefix != NULL); |
||||
pPrefix = ha->pPatchPrefix; |
||||
|
||||
// The patch name for "OldWorld\\XXX\\YYY" is "Base\\XXX\YYY"
|
||||
// We need to remove the "OldWorld\\" prefix
|
||||
if(!_strnicmp(szFileName, "OldWorld\\", 9)) |
||||
szFileName += 9; |
||||
|
||||
// Create the file name from the known patch entry
|
||||
memcpy(szBuffer, pPrefix->szPatchPrefix, pPrefix->nLength); |
||||
strcpy(szBuffer + pPrefix->nLength, szFileName); |
||||
szFileName = szBuffer; |
||||
} |
||||
|
||||
return szFileName; |
||||
} |
||||
|
||||
static bool OpenLocalFile(const char * szFileName, HANDLE * PtrFile) |
||||
{ |
||||
TFileStream * pStream; |
||||
TMPQFile * hf = NULL; |
||||
TCHAR szFileNameT[MAX_PATH]; |
||||
|
||||
// Convert the file name to UNICODE (if needed)
|
||||
StringCopy(szFileNameT, _countof(szFileNameT), szFileName); |
||||
|
||||
// Open the file and create the TMPQFile structure
|
||||
pStream = FileStream_OpenFile(szFileNameT, STREAM_FLAG_READ_ONLY); |
||||
if(pStream != NULL) |
||||
{ |
||||
// Allocate and initialize file handle
|
||||
hf = CreateFileHandle(NULL, NULL); |
||||
if(hf != NULL) |
||||
{ |
||||
hf->pStream = pStream; |
||||
*PtrFile = hf; |
||||
return true; |
||||
} |
||||
else |
||||
{ |
||||
FileStream_Close(pStream); |
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY); |
||||
} |
||||
} |
||||
*PtrFile = NULL; |
||||
return false; |
||||
} |
||||
|
||||
bool OpenPatchedFile(HANDLE hMpq, const char * szFileName, HANDLE * PtrFile) |
||||
{ |
||||
TMPQArchive * haBase = NULL; |
||||
TMPQArchive * ha = (TMPQArchive *)hMpq; |
||||
TFileEntry * pFileEntry; |
||||
TMPQFile * hfPatch; // Pointer to patch file
|
||||
TMPQFile * hfBase = NULL; // Pointer to base open file
|
||||
TMPQFile * hf = NULL; |
||||
HANDLE hPatchFile; |
||||
char szNameBuffer[MAX_PATH]; |
||||
|
||||
// First of all, find the latest archive where the file is in base version
|
||||
// (i.e. where the original, unpatched version of the file exists)
|
||||
while(ha != NULL) |
||||
{ |
||||
// If the file is there, then we remember the archive
|
||||
pFileEntry = GetFileEntryExact(ha, GetPatchFileName(ha, szFileName, szNameBuffer), 0, NULL); |
||||
if(pFileEntry != NULL && (pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) |
||||
haBase = ha; |
||||
|
||||
// Move to the patch archive
|
||||
ha = ha->haPatch; |
||||
} |
||||
|
||||
// If we couldn't find the base file in any of the patches, it doesn't exist
|
||||
if((ha = haBase) == NULL) |
||||
{ |
||||
SetLastError(ERROR_FILE_NOT_FOUND); |
||||
return false; |
||||
} |
||||
|
||||
// Now open the base file
|
||||
if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, (HANDLE *)&hfBase)) |
||||
{ |
||||
// The file must be a base file, i.e. without MPQ_FILE_PATCH_FILE
|
||||
assert((hfBase->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0); |
||||
hf = hfBase; |
||||
|
||||
// Now open all patches and attach them on top of the base file
|
||||
for(ha = ha->haPatch; ha != NULL; ha = ha->haPatch) |
||||
{ |
||||
// Prepare the file name with a correct prefix
|
||||
if(SFileOpenFileEx((HANDLE)ha, GetPatchFileName(ha, szFileName, szNameBuffer), SFILE_OPEN_BASE_FILE, &hPatchFile)) |
||||
{ |
||||
// Remember the new version
|
||||
hfPatch = (TMPQFile *)hPatchFile; |
||||
|
||||
// We should not find patch file
|
||||
assert((hfPatch->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) != 0); |
||||
|
||||
// Attach the patch to the base file
|
||||
hf->hfPatch = hfPatch; |
||||
hf = hfPatch; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Give the updated base MPQ
|
||||
if(PtrFile != NULL) |
||||
*PtrFile = (HANDLE)hfBase; |
||||
return (hfBase != NULL); |
||||
} |
||||
|
||||
/*****************************************************************************/ |
||||
/* Public functions */ |
||||
/*****************************************************************************/ |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileEnumLocales enums all locale versions within MPQ.
|
||||
// Functions fills all available language identifiers on a file into the buffer
|
||||
// pointed by plcLocales. There must be enough entries to copy the localed,
|
||||
// otherwise the function returns ERROR_INSUFFICIENT_BUFFER.
|
||||
|
||||
int WINAPI SFileEnumLocales( |
||||
HANDLE hMpq, |
||||
const char * szFileName, |
||||
LCID * PtrLocales, |
||||
LPDWORD PtrMaxLocales, |
||||
DWORD dwSearchScope) |
||||
{ |
||||
TMPQArchive * ha = (TMPQArchive *)hMpq; |
||||
TMPQHash * pFirstHash; |
||||
TMPQHash * pHash; |
||||
DWORD dwFileIndex = 0; |
||||
DWORD dwMaxLocales; |
||||
DWORD dwLocales = 0; |
||||
|
||||
// Test the parameters
|
||||
if(!IsValidMpqHandle(hMpq)) |
||||
return ERROR_INVALID_HANDLE; |
||||
if(szFileName == NULL || *szFileName == 0) |
||||
return ERROR_INVALID_PARAMETER; |
||||
if(ha->pHashTable == NULL) |
||||
return ERROR_NOT_SUPPORTED; |
||||
if(PtrMaxLocales == NULL) |
||||
return ERROR_INVALID_PARAMETER; |
||||
if(IsPseudoFileName(szFileName, &dwFileIndex)) |
||||
return ERROR_INVALID_PARAMETER; |
||||
|
||||
// Keep compiler happy
|
||||
dwMaxLocales = PtrMaxLocales[0]; |
||||
dwSearchScope = dwSearchScope; |
||||
|
||||
// Parse all files with that name
|
||||
pFirstHash = pHash = GetFirstHashEntry(ha, szFileName); |
||||
while(pHash != NULL) |
||||
{ |
||||
// Put the locales to the buffer
|
||||
if(PtrLocales != NULL && dwLocales < dwMaxLocales) |
||||
*PtrLocales++ = pHash->lcLocale; |
||||
dwLocales++; |
||||
|
||||
// Get the next locale
|
||||
pHash = GetNextHashEntry(ha, pFirstHash, pHash); |
||||
} |
||||
|
||||
// Give the caller the number of locales and return
|
||||
PtrMaxLocales[0] = dwLocales; |
||||
return (dwLocales <= dwMaxLocales) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileOpenFileEx
|
||||
//
|
||||
// hMpq - Handle of opened MPQ archive
|
||||
// szFileName - Name of file to open
|
||||
// dwSearchScope - Where to search
|
||||
// PtrFile - Pointer to store opened file handle
|
||||
|
||||
bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * PtrFile) |
||||
{ |
||||
TMPQArchive * ha = IsValidMpqHandle(hMpq); |
||||
TFileEntry * pFileEntry = NULL; |
||||
TMPQFile * hf = NULL; |
||||
DWORD dwHashIndex = HASH_ENTRY_FREE; |
||||
DWORD dwFileIndex = 0; |
||||
bool bOpenByIndex = false; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Don't accept NULL pointer to file handle
|
||||
if(szFileName == NULL || *szFileName == 0) |
||||
nError = ERROR_INVALID_PARAMETER; |
||||
|
||||
// When opening a file from MPQ, the handle must be valid
|
||||
if(dwSearchScope != SFILE_OPEN_LOCAL_FILE && ha == NULL) |
||||
nError = ERROR_INVALID_HANDLE; |
||||
|
||||
// When not checking for existence, the pointer to file handle must be valid
|
||||
if(dwSearchScope != SFILE_OPEN_CHECK_EXISTS && PtrFile == NULL) |
||||
nError = ERROR_INVALID_PARAMETER; |
||||
|
||||
// Prepare the file opening
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
switch(dwSearchScope) |
||||
{ |
||||
case SFILE_OPEN_FROM_MPQ: |
||||
case SFILE_OPEN_BASE_FILE: |
||||
case SFILE_OPEN_CHECK_EXISTS: |
||||
|
||||
// If this MPQ has no patches, open the file from this MPQ directly
|
||||
if(ha->haPatch == NULL || dwSearchScope == SFILE_OPEN_BASE_FILE) |
||||
{ |
||||
pFileEntry = GetFileEntryLocale2(ha, szFileName, lcFileLocale, &dwHashIndex); |
||||
} |
||||
|
||||
// If this MPQ is a patched archive, open the file as patched
|
||||
else |
||||
{ |
||||
return OpenPatchedFile(hMpq, szFileName, PtrFile); |
||||
} |
||||
break; |
||||
|
||||
case SFILE_OPEN_ANY_LOCALE: |
||||
|
||||
// This open option is reserved for opening MPQ internal listfile.
|
||||
// No argument validation. Tries to open file with neutral locale first,
|
||||
// then any other available.
|
||||
pFileEntry = GetFileEntryLocale2(ha, szFileName, 0, &dwHashIndex); |
||||
break; |
||||
|
||||
case SFILE_OPEN_LOCAL_FILE: |
||||
|
||||
// Open a local file
|
||||
return OpenLocalFile(szFileName, PtrFile);
|
||||
|
||||
default: |
||||
|
||||
// Don't accept any other value
|
||||
nError = ERROR_INVALID_PARAMETER; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Check whether the file really exists in the MPQ
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
if(pFileEntry == NULL || (pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) |
||||
{ |
||||
// Check the pseudo-file name
|
||||
if((bOpenByIndex = IsPseudoFileName(szFileName, &dwFileIndex)) == true) |
||||
{ |
||||
// Get the file entry for the file
|
||||
if(dwFileIndex < ha->dwFileTableSize) |
||||
{ |
||||
pFileEntry = ha->pFileTable + dwFileIndex; |
||||
} |
||||
} |
||||
|
||||
nError = ERROR_FILE_NOT_FOUND; |
||||
} |
||||
|
||||
// Ignore unknown loading flags (example: MPQ_2016_v1_WME4_4.w3x)
|
||||
// if(pFileEntry != NULL && pFileEntry->dwFlags & ~MPQ_FILE_VALID_FLAGS)
|
||||
// nError = ERROR_NOT_SUPPORTED;
|
||||
} |
||||
|
||||
// Did the caller just wanted to know if the file exists?
|
||||
if(nError == ERROR_SUCCESS && dwSearchScope != SFILE_OPEN_CHECK_EXISTS) |
||||
{ |
||||
// Allocate file handle
|
||||
hf = CreateFileHandle(ha, pFileEntry); |
||||
if(hf != NULL) |
||||
|
||||
{ |
||||
|
||||
// Get the hash index for the file
|
||||
if(ha->pHashTable != NULL && dwHashIndex == HASH_ENTRY_FREE) |
||||
dwHashIndex = FindHashIndex(ha, dwFileIndex); |
||||
if(dwHashIndex != HASH_ENTRY_FREE) |
||||
hf->pHashEntry = ha->pHashTable + dwHashIndex; |
||||
hf->dwHashIndex = dwHashIndex; |
||||
|
||||
// If the MPQ has sector CRC enabled, enable if for the file
|
||||
if(ha->dwFlags & MPQ_FLAG_CHECK_SECTOR_CRC) |
||||
hf->bCheckSectorCRCs = true; |
||||
|
||||
// If we know the real file name, copy it to the file entry
|
||||
if(bOpenByIndex == false) |
||||
{ |
||||
// If there is no file name yet, allocate it
|
||||
AllocateFileName(ha, pFileEntry, szFileName); |
||||
|
||||
// If the file is encrypted, we should detect the file key
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) |
||||
{ |
||||
hf->dwFileKey = DecryptFileKey(szFileName, |
||||
pFileEntry->ByteOffset, |
||||
pFileEntry->dwFileSize, |
||||
pFileEntry->dwFlags); |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
nError = ERROR_NOT_ENOUGH_MEMORY; |
||||
} |
||||
} |
||||
|
||||
// Give the file entry
|
||||
if(PtrFile != NULL) |
||||
PtrFile[0] = hf; |
||||
|
||||
// Return error code
|
||||
if(nError != ERROR_SUCCESS) |
||||
SetLastError(nError); |
||||
return (nError == ERROR_SUCCESS); |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileHasFile
|
||||
//
|
||||
// hMpq - Handle of opened MPQ archive
|
||||
// szFileName - Name of file to look for
|
||||
|
||||
bool WINAPI SFileHasFile(HANDLE hMpq, const char * szFileName) |
||||
{ |
||||
return SFileOpenFileEx(hMpq, szFileName, SFILE_OPEN_CHECK_EXISTS, NULL); |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// bool WINAPI SFileCloseFile(HANDLE hFile);
|
||||
|
||||
bool WINAPI SFileCloseFile(HANDLE hFile) |
||||
{ |
||||
TMPQFile * hf = (TMPQFile *)hFile; |
||||
|
||||
if(!IsValidFileHandle(hFile)) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return false; |
||||
} |
||||
|
||||
// Free the structure
|
||||
FreeFileHandle(hf); |
||||
return true; |
||||
} |
||||
@ -0,0 +1,907 @@
|
||||
/*****************************************************************************/ |
||||
/* SFileReadFile.cpp Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Description : */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* xx.xx.99 1.00 Lad The first version of SFileReadFile.cpp */ |
||||
/* 24.03.99 1.00 Lad Added the SFileGetFileInfo function */ |
||||
/*****************************************************************************/ |
||||
|
||||
#define __STORMLIB_SELF__ |
||||
#include "StormLib.h" |
||||
#include "StormCommon.h" |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Local functions
|
||||
|
||||
// hf - MPQ File handle.
|
||||
// pbBuffer - Pointer to target buffer to store sectors.
|
||||
// dwByteOffset - Position of sector in the file (relative to file begin)
|
||||
// dwBytesToRead - Number of bytes to read. Must be multiplier of sector size.
|
||||
// pdwBytesRead - Stored number of bytes loaded
|
||||
static int ReadMpqSectors(TMPQFile * hf, LPBYTE pbBuffer, DWORD dwByteOffset, DWORD dwBytesToRead, LPDWORD pdwBytesRead) |
||||
{ |
||||
ULONGLONG RawFilePos; |
||||
TMPQArchive * ha = hf->ha; |
||||
TFileEntry * pFileEntry = hf->pFileEntry; |
||||
LPBYTE pbRawSector = NULL; |
||||
LPBYTE pbOutSector = pbBuffer; |
||||
LPBYTE pbInSector = pbBuffer; |
||||
DWORD dwRawBytesToRead; |
||||
DWORD dwRawSectorOffset = dwByteOffset; |
||||
DWORD dwSectorsToRead = dwBytesToRead / ha->dwSectorSize; |
||||
DWORD dwSectorIndex = dwByteOffset / ha->dwSectorSize; |
||||
DWORD dwSectorsDone = 0; |
||||
DWORD dwBytesRead = 0; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Note that dwByteOffset must be aligned to size of one sector
|
||||
// Note that dwBytesToRead must be a multiplier of one sector size
|
||||
// This is local function, so we won't check if that's true.
|
||||
// Note that files stored in single units are processed by a separate function
|
||||
|
||||
// If there is not enough bytes remaining, cut dwBytesToRead
|
||||
if((dwByteOffset + dwBytesToRead) > hf->dwDataSize) |
||||
dwBytesToRead = hf->dwDataSize - dwByteOffset; |
||||
dwRawBytesToRead = dwBytesToRead; |
||||
|
||||
// Perform all necessary work to do with compressed files
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
||||
{ |
||||
// If the sector positions are not loaded yet, do it
|
||||
if(hf->SectorOffsets == NULL) |
||||
{ |
||||
nError = AllocateSectorOffsets(hf, true); |
||||
if(nError != ERROR_SUCCESS || hf->SectorOffsets == NULL) |
||||
return nError; |
||||
} |
||||
|
||||
// If the sector checksums are not loaded yet, load them now.
|
||||
if(hf->SectorChksums == NULL && (pFileEntry->dwFlags & MPQ_FILE_SECTOR_CRC) && hf->bLoadedSectorCRCs == false) |
||||
{ |
||||
//
|
||||
// Sector CRCs is plain crap feature. It is almost never present,
|
||||
// often it's empty, or the end offset of sector CRCs is zero.
|
||||
// We only try to load sector CRCs once, and regardless if it fails
|
||||
// or not, we won't try that again for the given file.
|
||||
//
|
||||
|
||||
AllocateSectorChecksums(hf, true); |
||||
hf->bLoadedSectorCRCs = true; |
||||
} |
||||
|
||||
// TODO: If the raw data MD5s are not loaded yet, load them now
|
||||
// Only do it if the MPQ is of format 4.0
|
||||
// if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_4 && ha->pHeader->dwRawChunkSize != 0)
|
||||
// {
|
||||
// nError = AllocateRawMD5s(hf, true);
|
||||
// if(nError != ERROR_SUCCESS)
|
||||
// return nError;
|
||||
// }
|
||||
|
||||
// Assign the temporary buffer as target for read operation
|
||||
dwRawSectorOffset = hf->SectorOffsets[dwSectorIndex]; |
||||
dwRawBytesToRead = hf->SectorOffsets[dwSectorIndex + dwSectorsToRead] - dwRawSectorOffset; |
||||
|
||||
// If the file is compressed, also allocate secondary buffer
|
||||
pbInSector = pbRawSector = STORM_ALLOC(BYTE, dwRawBytesToRead); |
||||
if(pbRawSector == NULL) |
||||
return ERROR_NOT_ENOUGH_MEMORY; |
||||
} |
||||
|
||||
// Calculate raw file offset where the sector(s) are stored.
|
||||
RawFilePos = CalculateRawSectorOffset(hf, dwRawSectorOffset); |
||||
|
||||
// Set file pointer and read all required sectors
|
||||
if(FileStream_Read(ha->pStream, &RawFilePos, pbInSector, dwRawBytesToRead)) |
||||
{ |
||||
// Now we have to decrypt and decompress all file sectors that have been loaded
|
||||
for(DWORD i = 0; i < dwSectorsToRead; i++) |
||||
{ |
||||
DWORD dwRawBytesInThisSector = ha->dwSectorSize; |
||||
DWORD dwBytesInThisSector = ha->dwSectorSize; |
||||
DWORD dwIndex = dwSectorIndex + i; |
||||
|
||||
// If there is not enough bytes in the last sector,
|
||||
// cut the number of bytes in this sector
|
||||
if(dwRawBytesInThisSector > dwBytesToRead) |
||||
dwRawBytesInThisSector = dwBytesToRead; |
||||
if(dwBytesInThisSector > dwBytesToRead) |
||||
dwBytesInThisSector = dwBytesToRead; |
||||
|
||||
// If the file is compressed, we have to adjust the raw sector size
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
||||
dwRawBytesInThisSector = hf->SectorOffsets[dwIndex + 1] - hf->SectorOffsets[dwIndex]; |
||||
|
||||
// If the file is encrypted, we have to decrypt the sector
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) |
||||
{ |
||||
BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector); |
||||
|
||||
// If we don't know the key, try to detect it by file content
|
||||
if(hf->dwFileKey == 0) |
||||
{ |
||||
hf->dwFileKey = DetectFileKeyByContent(pbInSector, dwBytesInThisSector, hf->dwDataSize); |
||||
if(hf->dwFileKey == 0) |
||||
{ |
||||
nError = ERROR_UNKNOWN_FILE_KEY; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
DecryptMpqBlock(pbInSector, dwRawBytesInThisSector, hf->dwFileKey + dwIndex); |
||||
BSWAP_ARRAY32_UNSIGNED(pbInSector, dwRawBytesInThisSector); |
||||
} |
||||
|
||||
#ifdef FULL |
||||
// If the file has sector CRC check turned on, perform it
|
||||
if(hf->bCheckSectorCRCs && hf->SectorChksums != NULL) |
||||
{ |
||||
DWORD dwAdlerExpected = hf->SectorChksums[dwIndex]; |
||||
DWORD dwAdlerValue = 0; |
||||
|
||||
// We can only check sector CRC when it's not zero
|
||||
// Neither can we check it if it's 0xFFFFFFFF.
|
||||
if(dwAdlerExpected != 0 && dwAdlerExpected != 0xFFFFFFFF) |
||||
{ |
||||
dwAdlerValue = adler32(0, pbInSector, dwRawBytesInThisSector); |
||||
if(dwAdlerValue != dwAdlerExpected) |
||||
{ |
||||
nError = ERROR_CHECKSUM_ERROR; |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
// If the sector is really compressed, decompress it.
|
||||
// WARNING : Some sectors may not be compressed, it can be determined only
|
||||
// by comparing uncompressed and compressed size !!!
|
||||
if(dwRawBytesInThisSector < dwBytesInThisSector) |
||||
{ |
||||
int cbOutSector = dwBytesInThisSector; |
||||
int cbInSector = dwRawBytesInThisSector; |
||||
int nResult = 0; |
||||
|
||||
// Is the file compressed by Blizzard's multiple compression ?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) |
||||
{ |
||||
// Remember the last used compression
|
||||
hf->dwCompression0 = pbInSector[0]; |
||||
|
||||
// Decompress the data
|
||||
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) |
||||
nResult = SCompDecompress2(pbOutSector, &cbOutSector, pbInSector, cbInSector); |
||||
else |
||||
nResult = SCompDecompress(pbOutSector, &cbOutSector, pbInSector, cbInSector); |
||||
} |
||||
|
||||
// Is the file compressed by PKWARE Data Compression Library ?
|
||||
else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) |
||||
{ |
||||
nResult = SCompExplode(pbOutSector, &cbOutSector, pbInSector, cbInSector); |
||||
} |
||||
|
||||
// Did the decompression fail ?
|
||||
if(nResult == 0) |
||||
{ |
||||
nError = ERROR_FILE_CORRUPT; |
||||
break; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if(pbOutSector != pbInSector) |
||||
memcpy(pbOutSector, pbInSector, dwBytesInThisSector); |
||||
} |
||||
|
||||
// Move pointers
|
||||
dwBytesToRead -= dwBytesInThisSector; |
||||
dwByteOffset += dwBytesInThisSector; |
||||
dwBytesRead += dwBytesInThisSector; |
||||
pbOutSector += dwBytesInThisSector; |
||||
pbInSector += dwRawBytesInThisSector; |
||||
dwSectorsDone++; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
nError = GetLastError(); |
||||
} |
||||
|
||||
// Free all used buffers
|
||||
if(pbRawSector != NULL) |
||||
STORM_FREE(pbRawSector); |
||||
|
||||
// Give the caller thenumber of bytes read
|
||||
*pdwBytesRead = dwBytesRead; |
||||
return nError; |
||||
} |
||||
|
||||
static int ReadMpqFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) |
||||
{ |
||||
ULONGLONG RawFilePos = hf->RawFilePos; |
||||
TMPQArchive * ha = hf->ha; |
||||
TFileEntry * pFileEntry = hf->pFileEntry; |
||||
LPBYTE pbCompressed = NULL; |
||||
LPBYTE pbRawData; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// If the file buffer is not allocated yet, do it.
|
||||
if(hf->pbFileSector == NULL) |
||||
{ |
||||
nError = AllocateSectorBuffer(hf); |
||||
if(nError != ERROR_SUCCESS || hf->pbFileSector == NULL) |
||||
return nError; |
||||
} |
||||
|
||||
// If the file is a patch file, adjust raw data offset
|
||||
if(hf->pPatchInfo != NULL) |
||||
RawFilePos += hf->pPatchInfo->dwLength; |
||||
pbRawData = hf->pbFileSector; |
||||
|
||||
// If the file sector is not loaded yet, do it
|
||||
if(hf->dwSectorOffs != 0) |
||||
{ |
||||
// Is the file compressed?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
||||
{ |
||||
// Allocate space for compressed data
|
||||
pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize); |
||||
if(pbCompressed == NULL) |
||||
return ERROR_NOT_ENOUGH_MEMORY; |
||||
pbRawData = pbCompressed; |
||||
} |
||||
|
||||
// Load the raw (compressed, encrypted) data
|
||||
if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize)) |
||||
{ |
||||
STORM_FREE(pbCompressed); |
||||
return GetLastError(); |
||||
} |
||||
|
||||
// If the file is encrypted, we have to decrypt the data first
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) |
||||
{ |
||||
BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize); |
||||
DecryptMpqBlock(pbRawData, pFileEntry->dwCmpSize, hf->dwFileKey); |
||||
BSWAP_ARRAY32_UNSIGNED(pbRawData, pFileEntry->dwCmpSize); |
||||
} |
||||
|
||||
// If the file is compressed, we have to decompress it now
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
||||
{ |
||||
int cbOutBuffer = (int)hf->dwDataSize; |
||||
int cbInBuffer = (int)pFileEntry->dwCmpSize; |
||||
int nResult = 0; |
||||
|
||||
//
|
||||
// If the file is an incremental patch, the size of compressed data
|
||||
// is determined as pFileEntry->dwCmpSize - sizeof(TPatchInfo)
|
||||
//
|
||||
// In "wow-update-12694.MPQ" from Wow-Cataclysm BETA:
|
||||
//
|
||||
// File CmprSize DcmpSize DataSize Compressed?
|
||||
// -------------------------------------- ---------- -------- -------- ---------------
|
||||
// esES\DBFilesClient\LightSkyBox.dbc 0xBE->0xA2 0xBC 0xBC Yes
|
||||
// deDE\DBFilesClient\MountCapability.dbc 0x93->0x77 0x77 0x77 No
|
||||
//
|
||||
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) |
||||
cbInBuffer = cbInBuffer - sizeof(TPatchInfo); |
||||
|
||||
// Is the file compressed by Blizzard's multiple compression ?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS) |
||||
{ |
||||
// Remember the last used compression
|
||||
hf->dwCompression0 = pbRawData[0]; |
||||
|
||||
// Decompress the file
|
||||
if(ha->pHeader->wFormatVersion >= MPQ_FORMAT_VERSION_2) |
||||
nResult = SCompDecompress2(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer); |
||||
else |
||||
nResult = SCompDecompress(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer); |
||||
} |
||||
|
||||
// Is the file compressed by PKWARE Data Compression Library ?
|
||||
// Note: Single unit files compressed with IMPLODE are not supported by Blizzard
|
||||
else if(pFileEntry->dwFlags & MPQ_FILE_IMPLODE) |
||||
nResult = SCompExplode(hf->pbFileSector, &cbOutBuffer, pbRawData, cbInBuffer); |
||||
|
||||
nError = (nResult != 0) ? ERROR_SUCCESS : ERROR_FILE_CORRUPT; |
||||
} |
||||
else |
||||
{ |
||||
if(hf->pbFileSector != NULL && pbRawData != hf->pbFileSector) |
||||
memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize); |
||||
} |
||||
|
||||
// Free the decompression buffer.
|
||||
if(pbCompressed != NULL) |
||||
STORM_FREE(pbCompressed); |
||||
|
||||
// The file sector is now properly loaded
|
||||
hf->dwSectorOffs = 0; |
||||
} |
||||
|
||||
// At this moment, we have the file loaded into the file buffer.
|
||||
// Copy as much as the caller wants
|
||||
if(nError == ERROR_SUCCESS && hf->dwSectorOffs == 0) |
||||
{ |
||||
// File position is greater or equal to file size ?
|
||||
if(dwFilePos >= hf->dwDataSize) |
||||
{ |
||||
*pdwBytesRead = 0; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
// If not enough bytes remaining in the file, cut them
|
||||
if((hf->dwDataSize - dwFilePos) < dwToRead) |
||||
dwToRead = (hf->dwDataSize - dwFilePos); |
||||
|
||||
// Copy the bytes
|
||||
memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead); |
||||
|
||||
// Give the number of bytes read
|
||||
*pdwBytesRead = dwToRead; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
// An error, sorry
|
||||
return ERROR_CAN_NOT_COMPLETE; |
||||
} |
||||
|
||||
static int ReadMpkFileSingleUnit(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) |
||||
{ |
||||
ULONGLONG RawFilePos = hf->RawFilePos + 0x0C; // For some reason, MPK files start at position (hf->RawFilePos + 0x0C)
|
||||
TMPQArchive * ha = hf->ha; |
||||
TFileEntry * pFileEntry = hf->pFileEntry; |
||||
LPBYTE pbCompressed = NULL; |
||||
LPBYTE pbRawData = hf->pbFileSector; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// We do not support patch files in MPK archives
|
||||
assert(hf->pPatchInfo == NULL); |
||||
|
||||
// If the file buffer is not allocated yet, do it.
|
||||
if(hf->pbFileSector == NULL) |
||||
{ |
||||
nError = AllocateSectorBuffer(hf); |
||||
if(nError != ERROR_SUCCESS || hf->pbFileSector == NULL) |
||||
return nError; |
||||
pbRawData = hf->pbFileSector; |
||||
} |
||||
|
||||
// If the file sector is not loaded yet, do it
|
||||
if(hf->dwSectorOffs != 0) |
||||
{ |
||||
// Is the file compressed?
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
||||
{ |
||||
// Allocate space for compressed data
|
||||
pbCompressed = STORM_ALLOC(BYTE, pFileEntry->dwCmpSize); |
||||
if(pbCompressed == NULL) |
||||
return ERROR_NOT_ENOUGH_MEMORY; |
||||
pbRawData = pbCompressed; |
||||
} |
||||
|
||||
// Load the raw (compressed, encrypted) data
|
||||
if(!FileStream_Read(ha->pStream, &RawFilePos, pbRawData, pFileEntry->dwCmpSize)) |
||||
{ |
||||
STORM_FREE(pbCompressed); |
||||
return GetLastError(); |
||||
} |
||||
|
||||
// If the file is encrypted, we have to decrypt the data first
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_ENCRYPTED) |
||||
{ |
||||
DecryptMpkTable(pbRawData, pFileEntry->dwCmpSize); |
||||
} |
||||
|
||||
// If the file is compressed, we have to decompress it now
|
||||
if(pFileEntry->dwFlags & MPQ_FILE_COMPRESS_MASK) |
||||
{ |
||||
#ifdef FULL |
||||
int cbOutBuffer = (int)hf->dwDataSize; |
||||
|
||||
hf->dwCompression0 = pbRawData[0]; |
||||
if(!SCompDecompressMpk(hf->pbFileSector, &cbOutBuffer, pbRawData, (int)pFileEntry->dwCmpSize)) |
||||
nError = ERROR_FILE_CORRUPT; |
||||
#else |
||||
assert(0); |
||||
#endif |
||||
} |
||||
else |
||||
{ |
||||
if(pbRawData != hf->pbFileSector) |
||||
memcpy(hf->pbFileSector, pbRawData, hf->dwDataSize); |
||||
} |
||||
|
||||
// Free the decompression buffer.
|
||||
if(pbCompressed != NULL) |
||||
STORM_FREE(pbCompressed); |
||||
|
||||
// The file sector is now properly loaded
|
||||
hf->dwSectorOffs = 0; |
||||
} |
||||
|
||||
// At this moment, we have the file loaded into the file buffer.
|
||||
// Copy as much as the caller wants
|
||||
if(nError == ERROR_SUCCESS && hf->dwSectorOffs == 0) |
||||
{ |
||||
// File position is greater or equal to file size ?
|
||||
if(dwFilePos >= hf->dwDataSize) |
||||
{ |
||||
*pdwBytesRead = 0; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
// If not enough bytes remaining in the file, cut them
|
||||
if((hf->dwDataSize - dwFilePos) < dwToRead) |
||||
dwToRead = (hf->dwDataSize - dwFilePos); |
||||
|
||||
// Copy the bytes
|
||||
memcpy(pvBuffer, hf->pbFileSector + dwFilePos, dwToRead); |
||||
|
||||
// Give the number of bytes read
|
||||
*pdwBytesRead = dwToRead; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
// An error, sorry
|
||||
return ERROR_CAN_NOT_COMPLETE; |
||||
} |
||||
|
||||
|
||||
static int ReadMpqFileSectorFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwBytesToRead, LPDWORD pdwBytesRead) |
||||
{ |
||||
TMPQArchive * ha = hf->ha; |
||||
LPBYTE pbBuffer = (BYTE *)pvBuffer; |
||||
DWORD dwTotalBytesRead = 0; // Total bytes read in all three parts
|
||||
DWORD dwSectorSizeMask = ha->dwSectorSize - 1; // Mask for block size, usually 0x0FFF
|
||||
DWORD dwFileSectorPos; // File offset of the loaded sector
|
||||
DWORD dwBytesRead; // Number of bytes read (temporary variable)
|
||||
int nError; |
||||
|
||||
// If the file position is at or beyond end of file, do nothing
|
||||
if(dwFilePos >= hf->dwDataSize) |
||||
{ |
||||
*pdwBytesRead = 0; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
// If not enough bytes in the file remaining, cut them
|
||||
if(dwBytesToRead > (hf->dwDataSize - dwFilePos)) |
||||
dwBytesToRead = (hf->dwDataSize - dwFilePos); |
||||
|
||||
// Compute sector position in the file
|
||||
dwFileSectorPos = dwFilePos & ~dwSectorSizeMask; // Position in the block
|
||||
|
||||
// If the file sector buffer is not allocated yet, do it now
|
||||
if(hf->pbFileSector == NULL) |
||||
{ |
||||
nError = AllocateSectorBuffer(hf); |
||||
if(nError != ERROR_SUCCESS || hf->pbFileSector == NULL) |
||||
return nError; |
||||
} |
||||
|
||||
// Load the first (incomplete) file sector
|
||||
if(dwFilePos & dwSectorSizeMask) |
||||
{ |
||||
DWORD dwBytesInSector = ha->dwSectorSize; |
||||
DWORD dwBufferOffs = dwFilePos & dwSectorSizeMask; |
||||
DWORD dwToCopy; |
||||
|
||||
// Is the file sector already loaded ?
|
||||
if(hf->dwSectorOffs != dwFileSectorPos) |
||||
{ |
||||
// Load one MPQ sector into archive buffer
|
||||
nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesInSector); |
||||
if(nError != ERROR_SUCCESS) |
||||
return nError; |
||||
|
||||
// Remember that the data loaded to the sector have new file offset
|
||||
hf->dwSectorOffs = dwFileSectorPos; |
||||
} |
||||
else |
||||
{ |
||||
if((dwFileSectorPos + dwBytesInSector) > hf->dwDataSize) |
||||
dwBytesInSector = hf->dwDataSize - dwFileSectorPos; |
||||
} |
||||
|
||||
// Copy the data from the offset in the loaded sector to the end of the sector
|
||||
dwToCopy = dwBytesInSector - dwBufferOffs; |
||||
if(dwToCopy > dwBytesToRead) |
||||
dwToCopy = dwBytesToRead; |
||||
|
||||
// Copy data from sector buffer into target buffer
|
||||
memcpy(pbBuffer, hf->pbFileSector + dwBufferOffs, dwToCopy); |
||||
|
||||
// Update pointers and byte counts
|
||||
dwTotalBytesRead += dwToCopy; |
||||
dwFileSectorPos += dwBytesInSector; |
||||
pbBuffer += dwToCopy; |
||||
dwBytesToRead -= dwToCopy; |
||||
} |
||||
|
||||
// Load the whole ("middle") sectors only if there is at least one full sector to be read
|
||||
if(dwBytesToRead >= ha->dwSectorSize) |
||||
{ |
||||
DWORD dwBlockBytes = dwBytesToRead & ~dwSectorSizeMask; |
||||
|
||||
// Load all sectors to the output buffer
|
||||
nError = ReadMpqSectors(hf, pbBuffer, dwFileSectorPos, dwBlockBytes, &dwBytesRead); |
||||
if(nError != ERROR_SUCCESS) |
||||
return nError; |
||||
|
||||
// Update pointers
|
||||
dwTotalBytesRead += dwBytesRead; |
||||
dwFileSectorPos += dwBytesRead; |
||||
pbBuffer += dwBytesRead; |
||||
dwBytesToRead -= dwBytesRead; |
||||
} |
||||
|
||||
// Read the terminating sector
|
||||
if(dwBytesToRead > 0) |
||||
{ |
||||
DWORD dwToCopy = ha->dwSectorSize; |
||||
|
||||
// Is the file sector already loaded ?
|
||||
if(hf->dwSectorOffs != dwFileSectorPos) |
||||
{ |
||||
// Load one MPQ sector into archive buffer
|
||||
nError = ReadMpqSectors(hf, hf->pbFileSector, dwFileSectorPos, ha->dwSectorSize, &dwBytesRead); |
||||
if(nError != ERROR_SUCCESS) |
||||
return nError; |
||||
|
||||
// Remember that the data loaded to the sector have new file offset
|
||||
hf->dwSectorOffs = dwFileSectorPos; |
||||
} |
||||
|
||||
// Check number of bytes read
|
||||
if(dwToCopy > dwBytesToRead) |
||||
dwToCopy = dwBytesToRead; |
||||
|
||||
// Copy the data from the cached last sector to the caller's buffer
|
||||
memcpy(pbBuffer, hf->pbFileSector, dwToCopy); |
||||
|
||||
// Update pointers
|
||||
dwTotalBytesRead += dwToCopy; |
||||
} |
||||
|
||||
// Store total number of bytes read to the caller
|
||||
*pdwBytesRead = dwTotalBytesRead; |
||||
return ERROR_SUCCESS; |
||||
} |
||||
|
||||
#ifdef FULL |
||||
static int ReadMpqFilePatchFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) |
||||
{ |
||||
TMPQPatcher Patcher; |
||||
DWORD dwBytesToRead = dwToRead; |
||||
DWORD dwBytesRead = 0; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Make sure that the patch file is loaded completely
|
||||
if(nError == ERROR_SUCCESS && hf->pbFileData == NULL) |
||||
{ |
||||
// Initialize patching process and allocate data
|
||||
nError = Patch_InitPatcher(&Patcher, hf); |
||||
if(nError != ERROR_SUCCESS) |
||||
return nError; |
||||
|
||||
// Set the current data size
|
||||
Patcher.cbFileData = hf->pFileEntry->dwFileSize; |
||||
|
||||
// Initialize the patcher object with initial file data
|
||||
if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) |
||||
nError = ReadMpqFileSingleUnit(hf, Patcher.pbFileData1, 0, Patcher.cbFileData, &dwBytesRead); |
||||
else |
||||
nError = ReadMpqFileSectorFile(hf, Patcher.pbFileData1, 0, Patcher.cbFileData, &dwBytesRead); |
||||
|
||||
// Perform the patching process
|
||||
if(nError == ERROR_SUCCESS) |
||||
nError = Patch_Process(&Patcher, hf); |
||||
|
||||
// Finalize the patcher structure
|
||||
Patch_Finalize(&Patcher); |
||||
dwBytesRead = 0; |
||||
} |
||||
|
||||
// If there is something to read, do it
|
||||
if(nError == ERROR_SUCCESS) |
||||
{ |
||||
if(dwFilePos < hf->cbFileData) |
||||
{ |
||||
// Make sure we don't copy more than file size
|
||||
if((dwFilePos + dwToRead) > hf->cbFileData) |
||||
dwToRead = hf->cbFileData - dwFilePos; |
||||
|
||||
// Copy the appropriate amount of the file data to the caller's buffer
|
||||
memcpy(pvBuffer, hf->pbFileData + dwFilePos, dwToRead); |
||||
dwBytesRead = dwToRead; |
||||
} |
||||
|
||||
// Set the proper error code
|
||||
nError = (dwBytesRead == dwBytesToRead) ? ERROR_SUCCESS : ERROR_HANDLE_EOF; |
||||
} |
||||
|
||||
// Give the result to the caller
|
||||
if(pdwBytesRead != NULL) |
||||
*pdwBytesRead = dwBytesRead; |
||||
return nError; |
||||
} |
||||
#endif |
||||
|
||||
static int ReadMpqFileLocalFile(TMPQFile * hf, void * pvBuffer, DWORD dwFilePos, DWORD dwToRead, LPDWORD pdwBytesRead) |
||||
{ |
||||
ULONGLONG FilePosition1 = dwFilePos; |
||||
ULONGLONG FilePosition2; |
||||
DWORD dwBytesRead = 0; |
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
assert(hf->pStream != NULL); |
||||
|
||||
// Because stream I/O functions are designed to read
|
||||
// "all or nothing", we compare file position before and after,
|
||||
// and if they differ, we assume that number of bytes read
|
||||
// is the difference between them
|
||||
|
||||
if(!FileStream_Read(hf->pStream, &FilePosition1, pvBuffer, dwToRead)) |
||||
{ |
||||
// If not all bytes have been read, then return the number of bytes read
|
||||
if((nError = GetLastError()) == ERROR_HANDLE_EOF) |
||||
{ |
||||
FileStream_GetPos(hf->pStream, &FilePosition2); |
||||
dwBytesRead = (DWORD)(FilePosition2 - FilePosition1); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
dwBytesRead = dwToRead; |
||||
} |
||||
|
||||
*pdwBytesRead = dwBytesRead; |
||||
return nError; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileReadFile
|
||||
|
||||
bool WINAPI SFileReadFile(HANDLE hFile, void * pvBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped) |
||||
{ |
||||
TMPQFile * hf = (TMPQFile *)hFile; |
||||
DWORD dwBytesRead = 0; // Number of bytes read
|
||||
int nError = ERROR_SUCCESS; |
||||
|
||||
// Always zero the result
|
||||
if(pdwRead != NULL) |
||||
*pdwRead = 0; |
||||
lpOverlapped = lpOverlapped; |
||||
|
||||
// Check valid parameters
|
||||
if(!IsValidFileHandle(hFile)) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return false; |
||||
} |
||||
|
||||
if(pvBuffer == NULL) |
||||
{ |
||||
SetLastError(ERROR_INVALID_PARAMETER); |
||||
return false; |
||||
} |
||||
|
||||
// If we didn't load the patch info yet, do it now
|
||||
if(hf->pFileEntry != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) && hf->pPatchInfo == NULL) |
||||
{ |
||||
nError = AllocatePatchInfo(hf, true); |
||||
if(nError != ERROR_SUCCESS || hf->pPatchInfo == NULL) |
||||
{ |
||||
SetLastError(nError); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
// Clear the last used compression
|
||||
hf->dwCompression0 = 0; |
||||
|
||||
// If the file is local file, read the data directly from the stream
|
||||
if(hf->pStream != NULL) |
||||
{ |
||||
nError = ReadMpqFileLocalFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); |
||||
} |
||||
#ifdef FULL |
||||
// If the file is a patch file, we have to read it special way
|
||||
else if(hf->hfPatch != NULL && (hf->pFileEntry->dwFlags & MPQ_FILE_PATCH_FILE) == 0) |
||||
{ |
||||
nError = ReadMpqFilePatchFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); |
||||
} |
||||
#endif |
||||
// If the archive is a MPK archive, we need special way to read the file
|
||||
else if(hf->ha->dwSubType == MPQ_SUBTYPE_MPK) |
||||
{ |
||||
nError = ReadMpkFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); |
||||
} |
||||
|
||||
// If the file is single unit file, redirect it to read file
|
||||
else if(hf->pFileEntry->dwFlags & MPQ_FILE_SINGLE_UNIT) |
||||
{ |
||||
nError = ReadMpqFileSingleUnit(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); |
||||
} |
||||
|
||||
// Otherwise read it as sector based MPQ file
|
||||
else |
||||
{ |
||||
nError = ReadMpqFileSectorFile(hf, pvBuffer, hf->dwFilePos, dwToRead, &dwBytesRead); |
||||
} |
||||
|
||||
// Increment the file position
|
||||
hf->dwFilePos += dwBytesRead; |
||||
|
||||
// Give the caller the number of bytes read
|
||||
if(pdwRead != NULL) |
||||
*pdwRead = dwBytesRead; |
||||
|
||||
// If the read operation succeeded, but not full number of bytes was read,
|
||||
// set the last error to ERROR_HANDLE_EOF
|
||||
if(nError == ERROR_SUCCESS && (dwBytesRead < dwToRead)) |
||||
nError = ERROR_HANDLE_EOF; |
||||
|
||||
// If something failed, set the last error value
|
||||
if(nError != ERROR_SUCCESS) |
||||
SetLastError(nError); |
||||
return (nError == ERROR_SUCCESS); |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SFileGetFileSize
|
||||
|
||||
DWORD WINAPI SFileGetFileSize(HANDLE hFile, LPDWORD pdwFileSizeHigh) |
||||
{ |
||||
ULONGLONG FileSize; |
||||
TMPQFile * hf = (TMPQFile *)hFile; |
||||
|
||||
// Validate the file handle before we go on
|
||||
if(IsValidFileHandle(hFile)) |
||||
{ |
||||
// Make sure that the variable is initialized
|
||||
FileSize = 0; |
||||
|
||||
// If the file is patched file, we have to get the size of the last version
|
||||
if(hf->hfPatch != NULL) |
||||
{ |
||||
// Walk through the entire patch chain, take the last version
|
||||
while(hf != NULL) |
||||
{ |
||||
// Get the size of the currently pointed version
|
||||
FileSize = hf->pFileEntry->dwFileSize; |
||||
|
||||
// Move to the next patch file in the hierarchy
|
||||
hf = hf->hfPatch; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// Is it a local file ?
|
||||
if(hf->pStream != NULL) |
||||
{ |
||||
FileStream_GetSize(hf->pStream, &FileSize); |
||||
} |
||||
else |
||||
{ |
||||
FileSize = hf->dwDataSize; |
||||
} |
||||
} |
||||
|
||||
// If opened from archive, return file size
|
||||
if(pdwFileSizeHigh != NULL) |
||||
*pdwFileSizeHigh = (DWORD)(FileSize >> 32); |
||||
return (DWORD)FileSize; |
||||
} |
||||
|
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return SFILE_INVALID_SIZE; |
||||
} |
||||
|
||||
DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod) |
||||
{ |
||||
TMPQFile * hf = (TMPQFile *)hFile; |
||||
ULONGLONG OldPosition; |
||||
ULONGLONG NewPosition; |
||||
ULONGLONG FileSize; |
||||
ULONGLONG DeltaPos; |
||||
|
||||
// If the hFile is not a valid file handle, return an error.
|
||||
if(!IsValidFileHandle(hFile)) |
||||
{ |
||||
SetLastError(ERROR_INVALID_HANDLE); |
||||
return SFILE_INVALID_POS; |
||||
} |
||||
|
||||
// Retrieve the file size for handling the limits
|
||||
if(hf->pStream != NULL) |
||||
{ |
||||
FileStream_GetSize(hf->pStream, &FileSize); |
||||
} |
||||
else |
||||
{ |
||||
FileSize = SFileGetFileSize(hFile, NULL); |
||||
} |
||||
|
||||
// Handle the NULL and non-NULL values of plFilePosHigh
|
||||
// Non-NULL: The DeltaPos is combined from lFilePos and *lpFilePosHigh
|
||||
// NULL: The DeltaPos is sign-extended value of lFilePos
|
||||
DeltaPos = (plFilePosHigh != NULL) ? MAKE_OFFSET64(plFilePosHigh[0], lFilePos) : (ULONGLONG)(LONGLONG)lFilePos; |
||||
|
||||
// Get the relative point where to move from
|
||||
switch(dwMoveMethod) |
||||
{ |
||||
case FILE_BEGIN: |
||||
|
||||
// Move relative to the file begin.
|
||||
OldPosition = 0; |
||||
break; |
||||
|
||||
case FILE_CURRENT: |
||||
|
||||
// Retrieve the current file position
|
||||
if(hf->pStream != NULL) |
||||
{ |
||||
FileStream_GetPos(hf->pStream, &OldPosition); |
||||
} |
||||
else |
||||
{ |
||||
OldPosition = hf->dwFilePos; |
||||
} |
||||
break; |
||||
|
||||
case FILE_END: |
||||
|
||||
// Move relative to the end of the file
|
||||
OldPosition = FileSize; |
||||
break; |
||||
|
||||
default: |
||||
SetLastError(ERROR_INVALID_PARAMETER); |
||||
return SFILE_INVALID_POS; |
||||
} |
||||
|
||||
// Calculate the new position
|
||||
NewPosition = OldPosition + DeltaPos; |
||||
|
||||
// If moving backward, don't allow the new position go negative
|
||||
if((LONGLONG)DeltaPos < 0) |
||||
{ |
||||
if(NewPosition > FileSize) // Position is negative
|
||||
{ |
||||
SetLastError(ERROR_NEGATIVE_SEEK); |
||||
return SFILE_INVALID_POS; |
||||
} |
||||
} |
||||
|
||||
// If moving forward, don't allow the new position go past the end of the file
|
||||
else |
||||
{ |
||||
if(NewPosition > FileSize) |
||||
NewPosition = FileSize; |
||||
} |
||||
|
||||
// Now apply the file pointer to the file
|
||||
if(hf->pStream != NULL) |
||||
{ |
||||
if(!FileStream_Read(hf->pStream, &NewPosition, NULL, 0)) |
||||
return SFILE_INVALID_POS; |
||||
} |
||||
else |
||||
{ |
||||
hf->dwFilePos = (DWORD)NewPosition; |
||||
} |
||||
|
||||
// Return the new file position
|
||||
if(plFilePosHigh != NULL) |
||||
*plFilePosHigh = (LONG)(NewPosition >> 32); |
||||
return (DWORD)NewPosition; |
||||
} |
||||
@ -0,0 +1,387 @@
|
||||
/*****************************************************************************/ |
||||
/* SCommon.h Copyright (c) Ladislav Zezula 2003 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Common functions for encryption/decryption from Storm.dll. Included by */ |
||||
/* SFile*** functions, do not include and do not use this file directly */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 24.03.03 1.00 Lad The first version of SFileCommon.h */ |
||||
/* 12.06.04 1.00 Lad Renamed to SCommon.h */ |
||||
/* 06.09.10 1.00 Lad Renamed to StormCommon.h */ |
||||
/*****************************************************************************/ |
||||
|
||||
#ifndef __STORMCOMMON_H__ |
||||
#define __STORMCOMMON_H__ |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Compression support
|
||||
|
||||
// Include functions from Pkware Data Compression Library
|
||||
#include "3rdParty/PKWare/pkware.h" |
||||
|
||||
#ifdef FULL |
||||
// Include functions from Huffmann compression
|
||||
#include "huffman/huff.h" |
||||
|
||||
// Include functions from IMA ADPCM compression
|
||||
#include "adpcm/adpcm.h" |
||||
|
||||
// Include functions from SPARSE compression
|
||||
#include "sparse/sparse.h" |
||||
|
||||
// Include functions from LZMA compression
|
||||
#include "lzma/C/LzmaEnc.h" |
||||
#include "lzma/C/LzmaDec.h" |
||||
|
||||
// Include functions from zlib
|
||||
#ifndef __SYS_ZLIB |
||||
#include "zlib/zlib.h" |
||||
#else |
||||
#include <zlib.h> |
||||
#endif |
||||
|
||||
// Include functions from bzlib
|
||||
#ifndef __SYS_BZLIB |
||||
#include "bzip2/bzlib.h" |
||||
#else |
||||
#include <bzlib.h> |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cryptography support
|
||||
|
||||
// Headers from LibTomCrypt
|
||||
#include "libtomcrypt/src/headers/tomcrypt.h" |
||||
|
||||
// For HashStringJenkins
|
||||
#include "jenkins/lookup.h" |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StormLib private defines
|
||||
|
||||
#define ID_MPQ_FILE 0x46494c45 // Used internally for checking TMPQFile ('FILE')
|
||||
|
||||
// Prevent problems with CRT "min" and "max" functions,
|
||||
// as they are not defined on all platforms
|
||||
#define STORMLIB_MIN(a, b) ((a < b) ? a : b) |
||||
#define STORMLIB_MAX(a, b) ((a > b) ? a : b) |
||||
#define STORMLIB_UNUSED(p) ((void)(p)) |
||||
|
||||
// Macro for building 64-bit file offset from two 32-bit
|
||||
#define MAKE_OFFSET64(hi, lo) (((ULONGLONG)hi << 32) | (ULONGLONG)lo) |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MPQ signature information
|
||||
|
||||
// Size of each signature type
|
||||
#define MPQ_WEAK_SIGNATURE_SIZE 64 |
||||
#define MPQ_STRONG_SIGNATURE_SIZE 256 |
||||
#define MPQ_STRONG_SIGNATURE_ID 0x5349474E // ID of the strong signature ("NGIS")
|
||||
#define MPQ_SIGNATURE_FILE_SIZE (MPQ_WEAK_SIGNATURE_SIZE + 8) |
||||
|
||||
// MPQ signature info
|
||||
typedef struct _MPQ_SIGNATURE_INFO |
||||
{ |
||||
ULONGLONG BeginMpqData; // File offset where the hashing starts
|
||||
ULONGLONG BeginExclude; // Begin of the excluded area (used for (signature) file)
|
||||
ULONGLONG EndExclude; // End of the excluded area (used for (signature) file)
|
||||
ULONGLONG EndMpqData; // File offset where the hashing ends
|
||||
ULONGLONG EndOfFile; // Size of the entire file
|
||||
BYTE Signature[MPQ_STRONG_SIGNATURE_SIZE + 0x10]; |
||||
DWORD cbSignatureSize; // Length of the signature
|
||||
DWORD SignatureTypes; // See SIGNATURE_TYPE_XXX
|
||||
|
||||
} MPQ_SIGNATURE_INFO, *PMPQ_SIGNATURE_INFO; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Memory management
|
||||
//
|
||||
// We use our own macros for allocating/freeing memory. If you want
|
||||
// to redefine them, please keep the following rules:
|
||||
//
|
||||
// - The memory allocation must return NULL if not enough memory
|
||||
// (i.e not to throw exception)
|
||||
// - The allocating function does not need to fill the allocated buffer with zeros
|
||||
// - Memory freeing function doesn't have to test the pointer to NULL
|
||||
//
|
||||
|
||||
//#if defined(_MSC_VER) && defined(_DEBUG)
|
||||
//
|
||||
//#define STORM_ALLOC(type, nitems) (type *)HeapAlloc(GetProcessHeap(), 0, ((nitems) * sizeof(type)))
|
||||
//#define STORM_REALLOC(type, ptr, nitems) (type *)HeapReAlloc(GetProcessHeap(), 0, ptr, ((nitems) * sizeof(type)))
|
||||
//#define STORM_FREE(ptr) HeapFree(GetProcessHeap(), 0, ptr)
|
||||
//
|
||||
//#else
|
||||
|
||||
#define STORM_ALLOC(type, nitems) (type *)malloc((nitems) * sizeof(type)) |
||||
#define STORM_REALLOC(type, ptr, nitems) (type *)realloc(ptr, ((nitems) * sizeof(type))) |
||||
#define STORM_FREE(ptr) free(ptr) |
||||
|
||||
//#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// StormLib internal global variables
|
||||
|
||||
extern LCID lcFileLocale; // Preferred file locale
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Conversion to uppercase/lowercase (and "/" to "\")
|
||||
|
||||
extern unsigned char AsciiToLowerTable[256]; |
||||
extern unsigned char AsciiToUpperTable[256]; |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Safe string functions
|
||||
|
||||
void StringCopy(char * szTarget, size_t cchTarget, const char * szSource); |
||||
void StringCat(char * szTarget, size_t cchTargetMax, const char * szSource); |
||||
|
||||
#ifdef _UNICODE |
||||
void StringCopy(TCHAR * szTarget, size_t cchTarget, const char * szSource); |
||||
void StringCopy(char * szTarget, size_t cchTarget, const TCHAR * szSource); |
||||
void StringCopy(TCHAR * szTarget, size_t cchTarget, const TCHAR * szSource); |
||||
void StringCat(TCHAR * szTarget, size_t cchTargetMax, const TCHAR * szSource); |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Encryption and decryption functions
|
||||
|
||||
#define MPQ_HASH_TABLE_INDEX 0x000 |
||||
#define MPQ_HASH_NAME_A 0x100 |
||||
#define MPQ_HASH_NAME_B 0x200 |
||||
#define MPQ_HASH_FILE_KEY 0x300 |
||||
#define MPQ_HASH_KEY2_MIX 0x400 |
||||
|
||||
DWORD HashString(const char * szFileName, DWORD dwHashType); |
||||
DWORD HashStringSlash(const char * szFileName, DWORD dwHashType); |
||||
DWORD HashStringLower(const char * szFileName, DWORD dwHashType); |
||||
|
||||
void InitializeMpqCryptography(); |
||||
|
||||
DWORD GetNearestPowerOfTwo(DWORD dwFileCount); |
||||
|
||||
bool IsPseudoFileName(const char * szFileName, LPDWORD pdwFileIndex); |
||||
ULONGLONG HashStringJenkins(const char * szFileName); |
||||
|
||||
DWORD GetDefaultSpecialFileFlags(DWORD dwFileSize, USHORT wFormatVersion); |
||||
|
||||
void EncryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey); |
||||
void DecryptMpqBlock(void * pvDataBlock, DWORD dwLength, DWORD dwKey); |
||||
|
||||
DWORD DetectFileKeyBySectorSize(LPDWORD EncryptedData, DWORD dwSectorSize, DWORD dwSectorOffsLen); |
||||
DWORD DetectFileKeyByContent(void * pvEncryptedData, DWORD dwSectorSize, DWORD dwFileSize); |
||||
DWORD DecryptFileKey(const char * szFileName, ULONGLONG MpqPos, DWORD dwFileSize, DWORD dwFlags); |
||||
|
||||
bool IsValidMD5(LPBYTE pbMd5); |
||||
bool IsValidSignature(LPBYTE pbSignature); |
||||
bool VerifyDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE expected_md5); |
||||
void CalculateDataBlockHash(void * pvDataBlock, DWORD cbDataBlock, LPBYTE md5_hash); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Handle validation functions
|
||||
|
||||
TMPQArchive * IsValidMpqHandle(HANDLE hMpq); |
||||
TMPQFile * IsValidFileHandle(HANDLE hFile); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for MPQ file tables
|
||||
|
||||
ULONGLONG FileOffsetFromMpqOffset(TMPQArchive * ha, ULONGLONG MpqOffset); |
||||
ULONGLONG CalculateRawSectorOffset(TMPQFile * hf, DWORD dwSectorOffset); |
||||
|
||||
int ConvertMpqHeaderToFormat4(TMPQArchive * ha, ULONGLONG MpqOffset, ULONGLONG FileSize, DWORD dwFlags, bool bIsWarcraft3Map); |
||||
|
||||
bool IsValidHashEntry(TMPQArchive * ha, TMPQHash * pHash); |
||||
|
||||
TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale); |
||||
TMPQHash * GetFirstHashEntry(TMPQArchive * ha, const char * szFileName); |
||||
TMPQHash * GetNextHashEntry(TMPQArchive * ha, TMPQHash * pFirstHash, TMPQHash * pPrevHash); |
||||
TMPQHash * AllocateHashEntry(TMPQArchive * ha, TFileEntry * pFileEntry, LCID lcLocale); |
||||
|
||||
TMPQExtHeader * LoadExtTable(TMPQArchive * ha, ULONGLONG ByteOffset, size_t Size, DWORD dwSignature, DWORD dwKey); |
||||
TMPQHetTable * LoadHetTable(TMPQArchive * ha); |
||||
TMPQBetTable * LoadBetTable(TMPQArchive * ha); |
||||
|
||||
TMPQBlock * LoadBlockTable(TMPQArchive * ha, bool bDontFixEntries = false); |
||||
TMPQBlock * TranslateBlockTable(TMPQArchive * ha, ULONGLONG * pcbTableSize, bool * pbNeedHiBlockTable); |
||||
|
||||
ULONGLONG FindFreeMpqSpace(TMPQArchive * ha); |
||||
|
||||
// Functions that load the HET and BET tables
|
||||
int CreateHashTable(TMPQArchive * ha, DWORD dwHashTableSize); |
||||
int LoadAnyHashTable(TMPQArchive * ha); |
||||
int BuildFileTable(TMPQArchive * ha); |
||||
int DefragmentFileTable(TMPQArchive * ha); |
||||
|
||||
int CreateFileTable(TMPQArchive * ha, DWORD dwFileTableSize); |
||||
int RebuildHetTable(TMPQArchive * ha); |
||||
int RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize); |
||||
int SaveMPQTables(TMPQArchive * ha); |
||||
|
||||
TMPQHetTable * CreateHetTable(DWORD dwEntryCount, DWORD dwTotalCount, DWORD dwHashBitSize, LPBYTE pbSrcData); |
||||
void FreeHetTable(TMPQHetTable * pHetTable); |
||||
|
||||
TMPQBetTable * CreateBetTable(DWORD dwMaxFileCount); |
||||
void FreeBetTable(TMPQBetTable * pBetTable); |
||||
|
||||
// Functions for finding files in the file table
|
||||
TFileEntry * GetFileEntryLocale2(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex); |
||||
TFileEntry * GetFileEntryLocale(TMPQArchive * ha, const char * szFileName, LCID lcLocale); |
||||
TFileEntry * GetFileEntryExact(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex); |
||||
|
||||
// Allocates file name in the file entry
|
||||
void AllocateFileName(TMPQArchive * ha, TFileEntry * pFileEntry, const char * szFileName); |
||||
|
||||
// Allocates new file entry in the MPQ tables. Reuses existing, if possible
|
||||
TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex); |
||||
int RenameFileEntry(TMPQArchive * ha, TMPQFile * hf, const char * szNewFileName); |
||||
int DeleteFileEntry(TMPQArchive * ha, TMPQFile * hf); |
||||
|
||||
// Invalidates entries for (listfile) and (attributes)
|
||||
void InvalidateInternalFiles(TMPQArchive * ha); |
||||
|
||||
// Retrieves information about the strong signature
|
||||
bool QueryMpqSignatureInfo(TMPQArchive * ha, PMPQ_SIGNATURE_INFO pSignatureInfo); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Support for alternate file formats (SBaseSubTypes.cpp)
|
||||
|
||||
int ConvertSqpHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags); |
||||
TMPQHash * LoadSqpHashTable(TMPQArchive * ha); |
||||
TMPQBlock * LoadSqpBlockTable(TMPQArchive * ha); |
||||
|
||||
int ConvertMpkHeaderToFormat4(TMPQArchive * ha, ULONGLONG FileSize, DWORD dwFlags); |
||||
void DecryptMpkTable(void * pvMpkTable, size_t cbSize); |
||||
TMPQHash * LoadMpkHashTable(TMPQArchive * ha); |
||||
TMPQBlock * LoadMpkBlockTable(TMPQArchive * ha); |
||||
int SCompDecompressMpk(void * pvOutBuffer, int * pcbOutBuffer, void * pvInBuffer, int cbInBuffer); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Common functions - MPQ File
|
||||
|
||||
TMPQFile * CreateFileHandle(TMPQArchive * ha, TFileEntry * pFileEntry); |
||||
TMPQFile * CreateWritableHandle(TMPQArchive * ha, DWORD dwFileSize); |
||||
void * LoadMpqTable(TMPQArchive * ha, ULONGLONG ByteOffset, DWORD dwCompressedSize, DWORD dwRealSize, DWORD dwKey, bool * pbTableIsCut); |
||||
int AllocateSectorBuffer(TMPQFile * hf); |
||||
int AllocatePatchInfo(TMPQFile * hf, bool bLoadFromFile); |
||||
int AllocateSectorOffsets(TMPQFile * hf, bool bLoadFromFile); |
||||
int AllocateSectorChecksums(TMPQFile * hf, bool bLoadFromFile); |
||||
int WritePatchInfo(TMPQFile * hf); |
||||
int WriteSectorOffsets(TMPQFile * hf); |
||||
int WriteSectorChecksums(TMPQFile * hf); |
||||
int WriteMemDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, void * pvRawData, DWORD dwRawDataSize, DWORD dwChunkSize, LPDWORD pcbTotalSize); |
||||
int WriteMpqDataMD5(TFileStream * pStream, ULONGLONG RawDataOffs, DWORD dwRawDataSize, DWORD dwChunkSize); |
||||
void FreeFileHandle(TMPQFile *& hf); |
||||
void FreeArchiveHandle(TMPQArchive *& ha); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Patch functions
|
||||
|
||||
// Structure used for the patching process
|
||||
typedef struct _TMPQPatcher |
||||
{ |
||||
BYTE this_md5[MD5_DIGEST_SIZE]; // MD5 of the current file state
|
||||
LPBYTE pbFileData1; // Primary working buffer
|
||||
LPBYTE pbFileData2; // Secondary working buffer
|
||||
DWORD cbMaxFileData; // Maximum allowed size of the patch data
|
||||
DWORD cbFileData; // Current size of the result data
|
||||
DWORD nCounter; // Counter of the patch process
|
||||
|
||||
} TMPQPatcher; |
||||
|
||||
bool IsIncrementalPatchFile(const void * pvData, DWORD cbData, LPDWORD pdwPatchedFileSize); |
||||
int Patch_InitPatcher(TMPQPatcher * pPatcher, TMPQFile * hf); |
||||
int Patch_Process(TMPQPatcher * pPatcher, TMPQFile * hf); |
||||
void Patch_Finalize(TMPQPatcher * pPatcher); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility functions
|
||||
|
||||
bool CheckWildCard(const char * szString, const char * szWildCard); |
||||
bool IsInternalMpqFileName(const char * szFileName); |
||||
|
||||
template <typename XCHAR> |
||||
const XCHAR * GetPlainFileName(const XCHAR * szFileName) |
||||
{ |
||||
const XCHAR * szPlainName = szFileName; |
||||
|
||||
while(*szFileName != 0) |
||||
{ |
||||
if(*szFileName == '\\' || *szFileName == '/') |
||||
szPlainName = szFileName + 1; |
||||
szFileName++; |
||||
} |
||||
|
||||
return szPlainName; |
||||
} |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Internal support for MPQ modifications
|
||||
|
||||
int SFileAddFile_Init( |
||||
TMPQArchive * ha, |
||||
const char * szArchivedName, |
||||
ULONGLONG ft, |
||||
DWORD dwFileSize, |
||||
LCID lcLocale, |
||||
DWORD dwFlags, |
||||
TMPQFile ** phf |
||||
); |
||||
|
||||
int SFileAddFile_Init( |
||||
TMPQArchive * ha, |
||||
TMPQFile * hfSrc, |
||||
TMPQFile ** phf |
||||
); |
||||
|
||||
int SFileAddFile_Write( |
||||
TMPQFile * hf, |
||||
const void * pvData, |
||||
DWORD dwSize, |
||||
DWORD dwCompression |
||||
); |
||||
|
||||
int SFileAddFile_Finish( |
||||
TMPQFile * hf |
||||
); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Attributes support
|
||||
|
||||
int SAttrLoadAttributes(TMPQArchive * ha); |
||||
int SAttrFileSaveToMpq(TMPQArchive * ha); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Listfile functions
|
||||
|
||||
int SListFileSaveToMpq(TMPQArchive * ha); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Weak signature support
|
||||
|
||||
int SSignFileCreate(TMPQArchive * ha); |
||||
int SSignFileFinish(TMPQArchive * ha); |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Dump data support
|
||||
|
||||
#ifdef __STORMLIB_DUMP_DATA__ |
||||
|
||||
void DumpMpqHeader(TMPQHeader * pHeader); |
||||
void DumpHashTable(TMPQHash * pHashTable, DWORD dwHashTableSize); |
||||
void DumpHetAndBetTable(TMPQHetTable * pHetTable, TMPQBetTable * pBetTable); |
||||
void DumpFileTable(TFileEntry * pFileTable, DWORD dwFileTableSize); |
||||
|
||||
#else |
||||
|
||||
#define DumpMpqHeader(h) /* */ |
||||
#define DumpHashTable(t, s) /* */ |
||||
#define DumpHetAndBetTable(t, s) /* */ |
||||
#define DumpFileTable(t, s) /* */ |
||||
|
||||
#endif |
||||
|
||||
#endif // __STORMCOMMON_H__
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,304 @@
|
||||
/*****************************************************************************/ |
||||
/* StormPort.h Copyright (c) Marko Friedemann 2001 */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Portability module for the StormLib library. Contains a wrapper symbols */ |
||||
/* to make the compilation under Linux work */ |
||||
/* */ |
||||
/* Author: Marko Friedemann <marko.friedemann@bmx-chemnitz.de> */ |
||||
/* Created at: Mon Jan 29 18:26:01 CEST 2001 */ |
||||
/* Computer: whiplash.flachland-chemnitz.de */ |
||||
/* System: Linux 2.4.0 on i686 */ |
||||
/* */ |
||||
/* Author: Sam Wilkins <swilkins1337@gmail.com> */ |
||||
/* System: Mac OS X and port to big endian processor */ |
||||
/* */ |
||||
/*---------------------------------------------------------------------------*/ |
||||
/* Date Ver Who Comment */ |
||||
/* -------- ---- --- ------- */ |
||||
/* 29.01.01 1.00 Mar Created */ |
||||
/* 24.03.03 1.01 Lad Some cosmetic changes */ |
||||
/* 12.11.03 1.02 Dan Macintosh compatibility */ |
||||
/* 24.07.04 1.03 Sam Mac OS X compatibility */ |
||||
/* 22.11.06 1.04 Sam Mac OS X compatibility (for StormLib 6.0) */ |
||||
/* 31.12.06 1.05 XPinguin Full GNU/Linux compatibility */ |
||||
/* 17.10.12 1.05 Lad Moved error codes so they don't overlap with errno.h */ |
||||
/*****************************************************************************/ |
||||
|
||||
#ifndef __STORMPORT_H__ |
||||
#define __STORMPORT_H__ |
||||
|
||||
#ifndef __cplusplus |
||||
#define bool char |
||||
#define true 1 |
||||
#define false 0 |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines for Windows
|
||||
|
||||
#if !defined(PLATFORM_DEFINED) && defined(_WIN32) |
||||
|
||||
// In MSVC 8.0, there are some functions declared as deprecated.
|
||||
#if _MSC_VER >= 1400 |
||||
#define _CRT_SECURE_NO_DEPRECATE |
||||
#define _CRT_NON_CONFORMING_SWPRINTFS |
||||
#endif |
||||
|
||||
#include <tchar.h> |
||||
#include <assert.h> |
||||
#include <ctype.h> |
||||
#include <stdio.h> |
||||
#include <windows.h> |
||||
#include <wininet.h> |
||||
#define PLATFORM_LITTLE_ENDIAN |
||||
|
||||
#ifdef _WIN64 |
||||
#define PLATFORM_64BIT |
||||
#else |
||||
#define PLATFORM_32BIT |
||||
#endif |
||||
|
||||
#define PLATFORM_WINDOWS |
||||
#define PLATFORM_DEFINED // The platform is known now
|
||||
|
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines for Mac
|
||||
|
||||
#if !defined(PLATFORM_DEFINED) && defined(__APPLE__) // Mac BSD API
|
||||
|
||||
// Macintosh
|
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <sys/mman.h> |
||||
#include <unistd.h> |
||||
#include <fcntl.h> |
||||
#include <stdlib.h> |
||||
#include <errno.h> |
||||
|
||||
// Support for PowerPC on Max OS X
|
||||
#if (__ppc__ == 1) || (__POWERPC__ == 1) || (_ARCH_PPC == 1) |
||||
#include <stdint.h> |
||||
#include <CoreFoundation/CFByteOrder.h> |
||||
#endif |
||||
|
||||
#define PKEXPORT |
||||
#define __SYS_ZLIB |
||||
#define __SYS_BZLIB |
||||
|
||||
#ifndef __BIG_ENDIAN__ |
||||
#define PLATFORM_LITTLE_ENDIAN |
||||
#endif |
||||
|
||||
#define PLATFORM_MAC |
||||
#define PLATFORM_DEFINED // The platform is known now
|
||||
|
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Assumption: we are not on Windows nor Macintosh, so this must be linux *grin*
|
||||
|
||||
#if !defined(PLATFORM_DEFINED) |
||||
|
||||
#include <sys/types.h> |
||||
#include <sys/stat.h> |
||||
#include <sys/mman.h> |
||||
#include <fcntl.h> |
||||
#include <unistd.h> |
||||
#include <stdint.h> |
||||
#include <stdlib.h> |
||||
#include <stdio.h> |
||||
#include <stdarg.h> |
||||
#include <string.h> |
||||
#include <ctype.h> |
||||
#include <assert.h> |
||||
#include <errno.h> |
||||
|
||||
#define PLATFORM_LITTLE_ENDIAN |
||||
#define PLATFORM_LINUX |
||||
#define PLATFORM_DEFINED |
||||
|
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Definition of Windows-specific types for non-Windows platforms
|
||||
|
||||
#ifndef PLATFORM_WINDOWS |
||||
#if __LP64__ |
||||
#define PLATFORM_64BIT |
||||
#else |
||||
#define PLATFORM_32BIT |
||||
#endif |
||||
|
||||
// Typedefs for ANSI C
|
||||
typedef unsigned char BYTE; |
||||
typedef unsigned short USHORT; |
||||
typedef int LONG; |
||||
typedef unsigned int DWORD; |
||||
typedef unsigned long DWORD_PTR; |
||||
typedef long LONG_PTR; |
||||
typedef long INT_PTR; |
||||
typedef long long LONGLONG; |
||||
typedef unsigned long long ULONGLONG; |
||||
typedef void * HANDLE; |
||||
typedef void * LPOVERLAPPED; // Unsupported on Linux and Mac
|
||||
typedef char TCHAR; |
||||
typedef unsigned int LCID; |
||||
typedef LONG * PLONG; |
||||
typedef DWORD * LPDWORD; |
||||
typedef BYTE * LPBYTE; |
||||
typedef const char * LPCTSTR; |
||||
typedef const char * LPCSTR; |
||||
typedef char * LPTSTR; |
||||
typedef char * LPSTR; |
||||
|
||||
#ifdef PLATFORM_32BIT |
||||
#define _LZMA_UINT32_IS_ULONG |
||||
#endif |
||||
|
||||
// Some Windows-specific defines
|
||||
#ifndef MAX_PATH |
||||
#define MAX_PATH 1024 |
||||
#endif |
||||
|
||||
#ifndef _countof |
||||
#define _countof(x) (sizeof(x) / sizeof(x[0])) |
||||
#endif |
||||
|
||||
#define WINAPI |
||||
|
||||
#define FILE_BEGIN SEEK_SET |
||||
#define FILE_CURRENT SEEK_CUR |
||||
#define FILE_END SEEK_END |
||||
|
||||
#define _T(x) x |
||||
#define _tcslen strlen |
||||
#define _tcscpy strcpy |
||||
#define _tcscat strcat |
||||
#define _tcschr strchr |
||||
#define _tcsrchr strrchr |
||||
#define _tcsstr strstr |
||||
#define _tcsnicmp strncasecmp |
||||
#define _tprintf printf |
||||
#define _stprintf sprintf |
||||
#define _tremove remove |
||||
#define _tmain main |
||||
|
||||
#define _stricmp strcasecmp |
||||
#define _strnicmp strncasecmp |
||||
#define _tcsicmp strcasecmp |
||||
#define _tcsnicmp strncasecmp |
||||
|
||||
#endif // !PLATFORM_WINDOWS
|
||||
|
||||
// 64-bit calls are supplied by "normal" calls on Mac
|
||||
#if defined(PLATFORM_MAC) |
||||
#define stat64 stat |
||||
#define fstat64 fstat |
||||
#define lseek64 lseek |
||||
#define ftruncate64 ftruncate |
||||
#define off64_t off_t |
||||
#define O_LARGEFILE 0 |
||||
#endif |
||||
|
||||
// Platform-specific error codes for UNIX-based platforms
|
||||
#if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) |
||||
#define ERROR_SUCCESS 0 |
||||
#define ERROR_FILE_NOT_FOUND ENOENT |
||||
#define ERROR_ACCESS_DENIED EPERM |
||||
#define ERROR_INVALID_HANDLE EBADF |
||||
#define ERROR_NOT_ENOUGH_MEMORY ENOMEM |
||||
#define ERROR_NOT_SUPPORTED ENOTSUP |
||||
#define ERROR_INVALID_PARAMETER EINVAL |
||||
#define ERROR_NEGATIVE_SEEK EINVAL |
||||
#define ERROR_DISK_FULL ENOSPC |
||||
#define ERROR_ALREADY_EXISTS EEXIST |
||||
#define ERROR_INSUFFICIENT_BUFFER ENOBUFS |
||||
#define ERROR_BAD_FORMAT 1000 // No such error code under Linux
|
||||
#define ERROR_NO_MORE_FILES 1001 // No such error code under Linux
|
||||
#define ERROR_HANDLE_EOF 1002 // No such error code under Linux
|
||||
#define ERROR_CAN_NOT_COMPLETE 1003 // No such error code under Linux
|
||||
#define ERROR_FILE_CORRUPT 1004 // No such error code under Linux
|
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Swapping functions
|
||||
|
||||
#ifdef PLATFORM_LITTLE_ENDIAN |
||||
#define BSWAP_INT16_UNSIGNED(a) (a) |
||||
#define BSWAP_INT16_SIGNED(a) (a) |
||||
#define BSWAP_INT32_UNSIGNED(a) (a) |
||||
#define BSWAP_INT32_SIGNED(a) (a) |
||||
#define BSWAP_INT64_SIGNED(a) (a) |
||||
#define BSWAP_INT64_UNSIGNED(a) (a) |
||||
#define BSWAP_ARRAY16_UNSIGNED(a,b) {} |
||||
#define BSWAP_ARRAY32_UNSIGNED(a,b) {} |
||||
#define BSWAP_ARRAY64_UNSIGNED(a,b) {} |
||||
#define BSWAP_PART_HEADER(a) {} |
||||
#define BSWAP_TMPQHEADER(a,b) {} |
||||
#define BSWAP_TMPKHEADER(a) {} |
||||
#else |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
int16_t SwapInt16(uint16_t); |
||||
uint16_t SwapUInt16(uint16_t); |
||||
int32_t SwapInt32(uint32_t); |
||||
uint32_t SwapUInt32(uint32_t); |
||||
int64_t SwapInt64(uint64_t); |
||||
uint64_t SwapUInt64(uint64_t); |
||||
void ConvertUInt16Buffer(void * ptr, size_t length); |
||||
void ConvertUInt32Buffer(void * ptr, size_t length); |
||||
void ConvertUInt64Buffer(void * ptr, size_t length); |
||||
void ConvertTMPQUserData(void *userData); |
||||
void ConvertTMPQHeader(void *header, uint16_t wPart); |
||||
void ConvertTMPKHeader(void *header); |
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
#define BSWAP_INT16_SIGNED(a) SwapInt16((a)) |
||||
#define BSWAP_INT16_UNSIGNED(a) SwapUInt16((a)) |
||||
#define BSWAP_INT32_SIGNED(a) SwapInt32((a)) |
||||
#define BSWAP_INT32_UNSIGNED(a) SwapUInt32((a)) |
||||
#define BSWAP_INT64_SIGNED(a) SwapInt64((a)) |
||||
#define BSWAP_INT64_UNSIGNED(a) SwapUInt64((a)) |
||||
#define BSWAP_ARRAY16_UNSIGNED(a,b) ConvertUInt16Buffer((a),(b)) |
||||
#define BSWAP_ARRAY32_UNSIGNED(a,b) ConvertUInt32Buffer((a),(b)) |
||||
#define BSWAP_ARRAY64_UNSIGNED(a,b) ConvertUInt64Buffer((a),(b)) |
||||
#define BSWAP_TMPQHEADER(a,b) ConvertTMPQHeader((a),(b)) |
||||
#define BSWAP_TMPKHEADER(a) ConvertTMPKHeader((a)) |
||||
#endif |
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Macro for deprecated symbols
|
||||
|
||||
/*
|
||||
#ifdef _MSC_VER |
||||
#if _MSC_FULL_VER >= 140050320 |
||||
#define STORMLIB_DEPRECATED(_Text) __declspec(deprecated(_Text)) |
||||
#else |
||||
#define STORMLIB_DEPRECATED(_Text) __declspec(deprecated) |
||||
#endif |
||||
#else |
||||
#ifdef __GNUC__ |
||||
#define STORMLIB_DEPRECATED(_Text) __attribute__((deprecated)) |
||||
#else |
||||
#define STORMLIB_DEPRECATED(_Text) __attribute__((deprecated(_Text))) |
||||
#endif |
||||
#endif |
||||
|
||||
// When a flag is deprecated, use this macro
|
||||
#ifndef _STORMLIB_NO_DEPRECATE |
||||
#define STORMLIB_DEPRECATED_FLAG(type, oldflag, newflag) \ |
||||
const STORMLIB_DEPRECATED(#oldflag " is deprecated. Use " #newflag ". To supress this warning, define _STORMLIB_NO_DEPRECATE") static type oldflag = (type)newflag; |
||||
#else |
||||
#define STORMLIB_DEPRECATED_FLAG(type, oldflag, newflag) static type oldflag = (type)newflag; |
||||
#endif |
||||
*/ |
||||
|
||||
#define bool int |
||||
void TranslateFileName(char* dst, int dstLen, const char* src); |
||||
|
||||
#endif // __STORMPORT_H__
|
||||
@ -0,0 +1,16 @@
|
||||
message(STATUS "Using 32-bit toolchain") |
||||
|
||||
set(CMAKE_CXX_FLAGS -m32 CACHE STRING "") |
||||
|
||||
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE) |
||||
|
||||
find_path(DIR NAMES cmake PATHS /usr/lib32 /usr/lib/i386-linux-gnu NO_DEFAULT_PATH) |
||||
|
||||
if(DIR) |
||||
message(STATUS "Using 32-bit libraries from ${DIR}") |
||||
# Read CMake modules from 32-bit packages |
||||
set(CMAKE_FIND_ROOT_PATH ${DIR}) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) |
||||
endif() |
||||
@ -0,0 +1,9 @@
|
||||
find_package(SDL2 REQUIRED) |
||||
# WORKAROUND: Arch Linux SDL2 cmake config not setting this variable |
||||
if(NOT SDL2_LIBRARIES) |
||||
# Note: you will probably need to install multilib/lib32-dbus on Arch |
||||
set(SDL2_LIBRARIES SDL2::SDL2) |
||||
endif() |
||||
|
||||
# WORKAROUND: Issue with Ubuntu 16.04 having whitespace (CMP0004) |
||||
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES) |
||||
@ -0,0 +1,3 @@
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) |
||||
message(WARNING [[In-source build detected, please eg. create a new directory and use `cmake ..`]]) |
||||
endif() |
||||
@ -0,0 +1,8 @@
|
||||
include(CheckCXXCompilerFlag) |
||||
|
||||
set(SANITIZE_OPTIONS -fsanitize=null -fsanitize=return) |
||||
|
||||
check_cxx_compiler_flag(HAS_SANITIZE_ADDRESS -fsanitize-recover=address) |
||||
if(HAS_SANITIZE_ADDRESS) |
||||
list(APPEND SANITIZE_OPTIONS -fsanitize=address -fsanitize-recover=address) |
||||
endif() |
||||
@ -0,0 +1,147 @@
|
||||
cmake_minimum_required(VERSION 3.5) |
||||
|
||||
include(CMake/out_of_tree.cmake) |
||||
|
||||
# This must be included before project() |
||||
include(CMake/32bit.cmake) |
||||
|
||||
set(CMAKE_CXX_STANDARD 11) |
||||
|
||||
|
||||
project(devil-miniwin |
||||
VERSION 0.0.1 |
||||
LANGUAGES CXX |
||||
) |
||||
|
||||
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 4) |
||||
message(WARNING "sizeof(void*) == ${CMAKE_SIZEOF_VOID_P}.") |
||||
message(FATAL_ERROR [[This project can only be compiled in 32-bit mode.]]) |
||||
endif() |
||||
|
||||
set(SOURCES |
||||
Source/automap.cpp |
||||
Source/codec.cpp |
||||
Source/control.cpp |
||||
Source/cursor.cpp |
||||
Source/dead.cpp |
||||
Source/debug.cpp |
||||
Source/diablo.cpp |
||||
Source/doom.cpp |
||||
Source/drlg_l1.cpp |
||||
Source/drlg_l2.cpp |
||||
Source/drlg_l3.cpp |
||||
Source/drlg_l4.cpp |
||||
# Source/effects.cpp |
||||
Source/encrypt.cpp |
||||
Source/engine.cpp |
||||
Source/error.cpp |
||||
Source/gamemenu.cpp |
||||
Source/gendung.cpp |
||||
Source/gmenu.cpp |
||||
Source/help.cpp |
||||
Source/interfac.cpp |
||||
Source/inv.cpp |
||||
Source/items.cpp |
||||
Source/lighting.cpp |
||||
Source/loadsave.cpp |
||||
Source/mainmenu.cpp |
||||
Source/minitext.cpp |
||||
Source/missiles.cpp |
||||
Source/monster.cpp |
||||
Source/mpqapi.cpp |
||||
Source/msgcmd.cpp |
||||
Source/msg.cpp |
||||
Source/multi.cpp |
||||
Source/objects.cpp |
||||
Source/pack.cpp |
||||
Source/palette.cpp |
||||
Source/path.cpp |
||||
Source/pfile.cpp |
||||
Source/player.cpp |
||||
Source/plrmsg.cpp |
||||
Source/portal.cpp |
||||
Source/quests.cpp |
||||
Source/render.cpp |
||||
Source/scrollrt.cpp |
||||
Source/setmaps.cpp |
||||
Source/sha.cpp |
||||
Source/spells.cpp |
||||
Source/stores.cpp |
||||
Source/sync.cpp |
||||
Source/textdat.cpp |
||||
Source/themes.cpp |
||||
Source/tmsg.cpp |
||||
Source/town.cpp |
||||
Source/towners.cpp |
||||
Source/track.cpp |
||||
Source/trigs.cpp |
||||
Source/wave.cpp |
||||
|
||||
3rdParty/PKWare/explode.cpp |
||||
3rdParty/PKWare/implode.cpp |
||||
) |
||||
|
||||
# Completely stubbed out sources, for reference |
||||
set(REPLACED_SOURCES |
||||
Source/capture.cpp |
||||
Source/appfat.cpp |
||||
Source/dthread.cpp |
||||
Source/dx.cpp |
||||
Source/fault.cpp |
||||
Source/init.cpp |
||||
Source/logging.cpp |
||||
Source/movie.cpp |
||||
Source/nthread.cpp |
||||
Source/restrict.cpp |
||||
Source/sound.cpp |
||||
Source/effects.cpp # There is a function here that references Dx3d and lead to crash. |
||||
) |
||||
|
||||
set(STUB_SOURCES |
||||
Stub/miniwin.cpp |
||||
Stub/miniwin_rand.cpp |
||||
Stub/appfat.cpp |
||||
Stub/capture.cpp |
||||
Stub/dthread.cpp |
||||
Stub/dx.cpp |
||||
Stub/effects.cpp |
||||
Stub/fault.cpp |
||||
Stub/init.cpp |
||||
Stub/movie.cpp |
||||
Stub/nthread.cpp |
||||
Stub/restrict.cpp |
||||
Stub/sound.cpp |
||||
Stub/storm.cpp |
||||
Stub/diabloui.cpp |
||||
Stub/miniwin_io.cpp |
||||
Stub/miniwin_sdl.cpp |
||||
Stub/storm_net.cpp |
||||
Stub/sdlrender.cpp |
||||
Stub/SDL_FontCache.cpp |
||||
|
||||
3rdParty/StormLib/src/FileStream.cpp |
||||
3rdParty/StormLib/src/SBaseCommon.cpp |
||||
3rdParty/StormLib/src/SBaseFileTable.cpp |
||||
3rdParty/StormLib/src/SBaseSubTypes.cpp |
||||
3rdParty/StormLib/src/SCompression.cpp |
||||
3rdParty/StormLib/src/SFileExtractFile.cpp |
||||
3rdParty/StormLib/src/SFileFindFile.cpp |
||||
3rdParty/StormLib/src/SFileGetFileInfo.cpp |
||||
3rdParty/StormLib/src/SFileOpenArchive.cpp |
||||
3rdParty/StormLib/src/SFileOpenFileEx.cpp |
||||
3rdParty/StormLib/src/SFileReadFile.cpp |
||||
) |
||||
|
||||
include(CMake/SDL2_fixed.cmake) |
||||
include(CMake/sanitize.cmake) |
||||
|
||||
include_directories(${SDL2_INCLUDE_DIRS}) |
||||
|
||||
include_directories(. Stub) |
||||
# FUTURE: use add_compile_definitions() |
||||
add_definitions(-DMINIWIN -D_DEBUG -DFASTER) |
||||
add_compile_options(-g -fpermissive -Wno-write-strings -Wno-multichar) |
||||
|
||||
add_executable(devil-test ${SOURCES} ${STUB_SOURCES} Stub/main_test.cpp) |
||||
target_compile_options(devil-test PRIVATE ${SANITIZE_OPTIONS}) |
||||
target_link_libraries(devil-test PUBLIC m ${SDL2_LIBRARIES} ${SANITIZE_OPTIONS}) |
||||
@ -0,0 +1,431 @@
|
||||
# Microsoft Developer Studio Project File - Name="Diablo" - Package Owner=<4> |
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
# ** DO NOT EDIT ** |
||||
|
||||
# TARGTYPE "Win32 (x86) Application" 0x0101 |
||||
|
||||
CFG=Diablo - Win32 Debug |
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
!MESSAGE use the Export Makefile command and run |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "Diablo.mak". |
||||
!MESSAGE |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "Diablo.mak" CFG="Diablo - Win32 Debug" |
||||
!MESSAGE |
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE |
||||
!MESSAGE "Diablo - Win32 Release" (based on "Win32 (x86) Application") |
||||
!MESSAGE "Diablo - Win32 Debug" (based on "Win32 (x86) Application") |
||||
!MESSAGE "Diablo - Win32 Release with PDB" (based on "Win32 (x86) Application") |
||||
!MESSAGE |
||||
|
||||
# Begin Project |
||||
# PROP AllowPerConfigDependencies 0 |
||||
# PROP Scc_ProjName "" |
||||
# PROP Scc_LocalPath "" |
||||
CPP=cl.exe |
||||
MTL=midl.exe |
||||
RSC=rc.exe |
||||
|
||||
!IF "$(CFG)" == "Diablo - Win32 Release" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "Source/WinRel" |
||||
# PROP BASE Intermediate_Dir "Source/WinRel" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "bld/WinRel" |
||||
# PROP Intermediate_Dir "Source/WinRel" |
||||
# PROP Ignore_Export_Lib 0 |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# SUBTRACT CPP /WX |
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 |
||||
# ADD LINK32 DiabloUI/WinRel/DiabloUI.lib 3rdParty/Storm/Source/WinRel/Storm.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 |
||||
|
||||
!ELSEIF "$(CFG)" == "Diablo - Win32 Debug" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "Diablo__" |
||||
# PROP BASE Intermediate_Dir "Diablo__" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 1 |
||||
# PROP Output_Dir "bld/WinDebug" |
||||
# PROP Intermediate_Dir "Source/WinDebug" |
||||
# PROP Ignore_Export_Lib 0 |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /MT /W3 /Gm /GX /Zi /O1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "NDEBUG" /YX /FD /c |
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD BASE MTL /nologo /D "_DEBUG" /D "NDEBUG" /mktyplib203 /o "NUL" /win32 /win32 |
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 /win32 |
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "_DEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept |
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 |
||||
/nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept |
||||
|
||||
!ELSEIF "$(CFG)" == "Diablo - Win32 Release with PDB" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "Diablo___Win32_Release_with_PDB" |
||||
# PROP BASE Intermediate_Dir "Diablo___Win32_Release_with_PDB" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "bld/WinRel" |
||||
# PROP Intermediate_Dir "Source/WinRel" |
||||
# PROP Ignore_Export_Lib 0 |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# SUBTRACT BASE CPP /WX |
||||
# ADD CPP /nologo /MT /W3 /GX /Zi /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# SUBTRACT CPP /WX |
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 DiabloUI/WinRel/DiabloUI.lib 3rdParty/Storm/Source/WinRel/Storm.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /machine:I386 |
||||
# ADD LINK32 DiabloUI/WinRel/DiabloUI.lib 3rdParty/Storm/Source/WinRel/Storm.lib kernel32.lib user32.lib gdi32.lib advapi32.lib shell32.lib version.lib /nologo /subsystem:windows /debug /machine:I386 |
||||
|
||||
!ENDIF |
||||
|
||||
# Begin Target |
||||
|
||||
# Name "Diablo - Win32 Release" |
||||
# Name "Diablo - Win32 Debug" |
||||
# Name "Diablo - Win32 Release with PDB" |
||||
# Begin Group "Source Files" |
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\appfat.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\automap.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\capture.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\codec.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\control.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\cursor.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\dead.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\debug.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\diablo.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\doom.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\drlg_l1.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\drlg_l2.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\drlg_l3.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\drlg_l4.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\dthread.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\dx.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\effects.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\encrypt.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\engine.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\error.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\fault.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\gamemenu.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\gendung.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\gmenu.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\help.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\init.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\interfac.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\inv.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\items.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\lighting.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\loadsave.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\logging.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\mainmenu.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\minitext.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\missiles.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\monster.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\movie.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\mpqapi.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\msg.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\msgcmd.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\multi.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\nthread.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\objects.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\pack.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\palette.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\path.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\pfile.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\player.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\plrmsg.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\portal.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\quests.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\restrict.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\scrollrt.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\setmaps.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\sha.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\sound.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\spells.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\stores.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\sync.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\textdat.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\themes.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\tmsg.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\town.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\towners.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\track.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\trigs.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\wave.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Source\render.cpp |
||||
# End Source File |
||||
# End Group |
||||
# Begin Group "Resource Files" |
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Diablo.ico |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\Diablo.rc |
||||
# End Source File |
||||
# End Group |
||||
# Begin Group "Header Files" |
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\resource.h |
||||
# End Source File |
||||
# End Group |
||||
# Begin Group "PKWare" |
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\3rdParty\PKWare\explode.cpp |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\3rdParty\PKWare\implode.cpp |
||||
# End Source File |
||||
# End Group |
||||
# End Target |
||||
# End Project |
||||
@ -0,0 +1,59 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00 |
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! |
||||
|
||||
############################################################################### |
||||
|
||||
Project: "Diablo"=".\Diablo.dsp" - Package Owner=<4> |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<4> |
||||
{{{ |
||||
Begin Project Dependency |
||||
Project_Dep_Name DiabloUI |
||||
End Project Dependency |
||||
Begin Project Dependency |
||||
Project_Dep_Name Storm |
||||
End Project Dependency |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
Project: "DiabloUI"=".\DiabloUI\DiabloUI.dsp" - Package Owner=<4> |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<4> |
||||
{{{ |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
Project: "Storm"=".\3rdParty\Storm\Source\Storm.dsp" - Package Owner=<4> |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<4> |
||||
{{{ |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
Global: |
||||
|
||||
Package=<5> |
||||
{{{ |
||||
}}} |
||||
|
||||
Package=<3> |
||||
{{{ |
||||
}}} |
||||
|
||||
############################################################################### |
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,291 @@
|
||||
//Microsoft Developer Studio generated resource script. |
||||
// |
||||
#include "resource.h" |
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS |
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// |
||||
// Generated from the TEXTINCLUDE 2 resource. |
||||
// |
||||
#include "afxres.h" |
||||
|
||||
///////////////////////////////////////////////////////////////////////////// |
||||
#undef APSTUDIO_READONLY_SYMBOLS |
||||
|
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// English (U.S.) resources |
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) |
||||
#ifdef _WIN32 |
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US |
||||
#pragma code_page(1252) |
||||
#endif //_WIN32 |
||||
|
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// |
||||
// Icon |
||||
// |
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon |
||||
// remains consistent on all systems. |
||||
IDI_ICON1 ICON DISCARDABLE "Diablo.ico" |
||||
|
||||
#ifdef APSTUDIO_INVOKED |
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// |
||||
// TEXTINCLUDE |
||||
// |
||||
|
||||
1 TEXTINCLUDE DISCARDABLE |
||||
BEGIN |
||||
"resource.h\0" |
||||
END |
||||
|
||||
2 TEXTINCLUDE DISCARDABLE |
||||
BEGIN |
||||
"#include ""afxres.h""\r\n" |
||||
"\0" |
||||
END |
||||
|
||||
3 TEXTINCLUDE DISCARDABLE |
||||
BEGIN |
||||
"\r\n" |
||||
"\0" |
||||
END |
||||
|
||||
#endif // APSTUDIO_INVOKED |
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// |
||||
// Dialog |
||||
// |
||||
|
||||
IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 250, 241 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Direct Draw Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,193,220,50,14 |
||||
LTEXT "Diablo was unable to properly initialize your video card using DirectX. Please try the following solutions to correct the problem:", |
||||
-1,7,7,236,18 |
||||
LTEXT "Use the Diablo setup program ""SETUP.EXE"" provided on the Diablo CD-ROM to install DirectX 3.0.", |
||||
-1,19,26,210,18 |
||||
LTEXT "Install the most recent DirectX video drivers provided by the manufacturer of your video card. A list of video card manufactuers can be found at: http://www.blizzard.com/support/vendors.htm", |
||||
-1,19,48,210,27 |
||||
LTEXT "The error encountered while trying to initialize the video card was:", |
||||
-1,7,175,236,9 |
||||
LTEXT "unknown error",1000,19,186,210,27 |
||||
LTEXT "If you continue to have problems, we have also included Microsoft DirectX 2.0 drivers on the Diablo CD-ROM. This older version of DirectX may work in cases where DirectX 3.0 does not.", |
||||
-1,7,79,236,27 |
||||
LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", |
||||
-1,19,137,210,27 |
||||
LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", |
||||
-1,7,116,236,18 |
||||
END |
||||
|
||||
IDD_DIALOG2 DIALOG DISCARDABLE 0, 0, 250, 213 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Out of Memory Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,193,192,50,14 |
||||
LTEXT "Diablo has exhausted all the memory on your system. This problem can likely be corrected by changing the virtual memory settings for Windows. Ensure that your system has at least 10 megabytes of free disk space, then check your virtual memory settings:", |
||||
-1,7,7,236,36 |
||||
LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""System"" control panel applet\nSelect the ""Performance"" tab, and press ""Virtual Memory""\nUse the ""Let Windows manage my virtual memory..."" option", |
||||
-1,23,54,197,36 |
||||
LTEXT "The error encountered was:",-1,7,146,236,11 |
||||
LTEXT "unknown location",1000,20,157,210,27 |
||||
LTEXT "For Windows 95:",-1,7,45,236,9 |
||||
LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""System"" control panel applet\nSelect the ""Performance"" tab\nPress ""Change"" in ""Virtual Memory"" settings\nEnsure that the virtual memory file is at least 32 megabytes", |
||||
-1,17,98,197,45 |
||||
LTEXT "For Windows NT:",-1,7,89,236,9 |
||||
END |
||||
|
||||
IDD_DIALOG3 DIALOG DISCARDABLE 0, 0, 265, 114 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Data File Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,208,93,50,14 |
||||
LTEXT "Diablo was unable to open a required file. Please ensure that the Diablo disc is in the CDROM drive. If this problem persists, try uninstalling and reinstalling Diablo using the program ""SETUP.EXE"" on the Diablo CD-ROM.", |
||||
-1,7,7,251,36 |
||||
LTEXT "The problem occurred while trying to load a file",-1,7, |
||||
48,232,9 |
||||
LTEXT "unknown file",1000,20,59,210,27 |
||||
END |
||||
|
||||
IDD_DIALOG4 DIALOG DISCARDABLE 0, 0, 250, 161 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Direct Draw Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,193,140,50,14 |
||||
LTEXT "Diablo was unable to find the file ""ddraw.dll"", which is a component of Microsoft DirectX. Please run the program ""SETUP.EXE"" on the Diablo CD-ROM and install Microsoft DirectX.", |
||||
-1,7,7,236,27 |
||||
LTEXT "The error encountered while trying to initialize DirectX was:", |
||||
-1,7,95,236,9 |
||||
LTEXT "unknown error",1000,19,106,210,29 |
||||
LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", |
||||
-1,19,60,210,27 |
||||
LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", |
||||
-1,7,39,236,18 |
||||
END |
||||
|
||||
IDD_DIALOG5 DIALOG DISCARDABLE 0, 0, 250, 161 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Direct Sound Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,193,140,50,14 |
||||
LTEXT "Diablo was unable to find the file ""dsound.dll"", which is a component of Microsoft DirectX. Please run the program ""SETUP.EXE"" on the Diablo CD-ROM and install Microsoft DirectX.", |
||||
-1,7,7,236,27 |
||||
LTEXT "The error encountered while trying to initialize DirectX was:", |
||||
-1,7,95,236,9 |
||||
LTEXT "unknown error",1000,19,106,210,27 |
||||
LTEXT "USA telephone: 1-800-426-9400\nInternational telephone: 206-882-8080\nhttp://www.microsoft.com", |
||||
-1,19,60,210,27 |
||||
LTEXT "If you continue to have problems with DirectX, please contact Microsoft's Technical Support at:", |
||||
-1,7,39,236,18 |
||||
END |
||||
|
||||
/* IDD_DIALOG6 DIALOG DISCARDABLE 0, 0, 250, 92 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "System warning" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "&OK",1,130,71,50,14 |
||||
LTEXT "Diablo requires an Intel Pentium-class processor to run properly. Your system does not appear to have a Pentium-class processor installed.", |
||||
-1,7,7,236,18 |
||||
LTEXT "You may still be able to play Diablo if your processor has the performance characteristics of a Pentium.", |
||||
-1,7,30,236,18 |
||||
LTEXT "Press ""OK"" to proceed, otherwise press ""Cancel"" to exit this program.", |
||||
-1,7,53,236,9 |
||||
PUSHBUTTON "&Cancel",2,193,71,50,14 |
||||
END */ |
||||
|
||||
IDD_DIALOG7 DIALOG DISCARDABLE 0, 0, 250, 100 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Out of Disk Space" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,193,79,50,14 |
||||
LTEXT "Diablo requires at least 10 megabytes of free disk space to run properly. The disk:", |
||||
-1,7,7,236,18 |
||||
LTEXT "",-1,7,43,232,9 |
||||
LTEXT "unknown drive",1000,7,33,210,9 |
||||
LTEXT "has less than 10 megabytes of free space left. Please free some space on your drive and run Diablo again.", |
||||
-1,7,52,236,18 |
||||
END |
||||
|
||||
IDD_DIALOG8 DIALOG DISCARDABLE 0, 0, 250, 161 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Direct Draw Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,193,140,50,14 |
||||
LTEXT "Diablo was unable to switch video modes. This is a common problem for computers with more than one video card. To correct this problem, please set your video resolution to 640 x 480 and try running Diablo again.", |
||||
-1,7,7,236,27 |
||||
LTEXT "The error encountered while trying to switch video modes was:", |
||||
-1,7,95,236,9 |
||||
LTEXT "unknown error",1000,19,106,210,27 |
||||
LTEXT "Select ""Settings - Control Panel"" from the ""Start"" menu\nRun the ""Display"" control panel applet\nSelect the ""Settings"" tab\nSet the ""Desktop Area"" to ""640 x 480 pixels""", |
||||
-1,23,50,197,36 |
||||
LTEXT "For Windows 95 and Windows NT",-1,7,41,236,9 |
||||
END |
||||
|
||||
IDD_DIALOG9 DIALOG DISCARDABLE 0, 0, 250, 92 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Data File Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,136,71,50,14 |
||||
LTEXT "Diablo cannot read a required data file. Your Diablo CD may not be in the CDROM drive. Please ensure that the Diablo disc is in the CDROM drive and press OK. To leave the program, press Exit.", |
||||
-1,7,7,236,27 |
||||
LTEXT "unknown file",1000,20,37,210,27 |
||||
PUSHBUTTON "Exit",2,193,71,50,14 |
||||
END |
||||
|
||||
IDD_DIALOG10 DIALOG DISCARDABLE 0, 0, 223, 116 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Windows 2000 Restricted User Advisory" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,166,95,50,14 |
||||
LTEXT "In order to install, play or patch Diablo using the Windows 2000 operating system, you will need to log in as either an Administrator or as a Power User.", |
||||
-1,7,7,209,28 |
||||
LTEXT "Users, also known as Restricted Users, do not have sufficient access to install or play the game properly.", |
||||
-1,7,39,209,20 |
||||
LTEXT "If you have further questions regarding User Rights in Windows 2000, please refer to your Windows 2000 documentation or contact your system administrator.", |
||||
-1,7,63,209,28 |
||||
END |
||||
|
||||
IDD_DIALOG11 DIALOG DISCARDABLE 0, 0, 220, 121 |
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU |
||||
CAPTION "Read-Only Directory Error" |
||||
FONT 8, "MS Sans Serif" |
||||
BEGIN |
||||
DEFPUSHBUTTON "OK",1,163,100,50,14 |
||||
LTEXT "Diablo is being run from:",-1,7,7,206,10 |
||||
LTEXT "unknown directory",1000,17,20,186,20 |
||||
LTEXT "Diablo or the current user does not seem to have write privilages in this directory. Contact your system administrator.\n\nNote that Windows 2000 Restricted Users can not write to the Windows or Program Files directory hierarchies.", |
||||
-1,7,44,206,50 |
||||
END |
||||
|
||||
|
||||
#ifndef _MAC |
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// |
||||
// Version |
||||
// |
||||
|
||||
VS_VERSION_INFO VERSIONINFO |
||||
FILEVERSION 2001,5,18,1 |
||||
PRODUCTVERSION 1,0,9,2 |
||||
FILEFLAGSMASK 0x3fL |
||||
#ifdef _DEBUG |
||||
FILEFLAGS 0x1L |
||||
#else |
||||
FILEFLAGS 0x0L |
||||
#endif |
||||
FILEOS 0x4L |
||||
FILETYPE 0x1L |
||||
FILESUBTYPE 0x0L |
||||
BEGIN |
||||
BLOCK "StringFileInfo" |
||||
BEGIN |
||||
BLOCK "040904b0" |
||||
BEGIN |
||||
VALUE "CompanyName", "Blizzard Entertainment\0" |
||||
VALUE "FileDescription", "Diablo\0" |
||||
VALUE "FileVersion", "2001, 5, 18, 1\0" |
||||
VALUE "InternalName", "Diablo\0" |
||||
VALUE "LegalCopyright", "Copyright © 1996-2001\0" |
||||
VALUE "OriginalFilename", "Diablo.exe\0" |
||||
VALUE "ProductName", "Blizzard Entertainment Diablo\0" |
||||
VALUE "ProductVersion", "1, 0, 9, 2\0" |
||||
END |
||||
END |
||||
BLOCK "VarFileInfo" |
||||
BEGIN |
||||
VALUE "Translation", 0x409, 1200 |
||||
END |
||||
END |
||||
|
||||
#endif // !_MAC |
||||
|
||||
#endif // English (U.S.) resources |
||||
///////////////////////////////////////////////////////////////////////////// |
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED |
||||
///////////////////////////////////////////////////////////////////////////// |
||||
// |
||||
// Generated from the TEXTINCLUDE 3 resource. |
||||
// |
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////// |
||||
#endif // not APSTUDIO_INVOKED |
||||
|
||||
@ -0,0 +1,37 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
# Visual Studio 15 |
||||
VisualStudioVersion = 15.0.27703.2035 |
||||
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Diablo", "Diablo.vcxproj", "{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DiabloUI", "DiabloUI\DiabloUI.vcxproj", "{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}" |
||||
EndProject |
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Storm", "3rdParty\Storm\Source\Storm.vcxproj", "{B28F69CE-15A1-424D-BBB5-2727258D675B}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|x86 = Debug|x86 |
||||
Release|x86 = Release|x86 |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Debug|x86.ActiveCfg = Debug|Win32 |
||||
{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Debug|x86.Build.0 = Debug|Win32 |
||||
{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Release|x86.ActiveCfg = Release|Win32 |
||||
{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}.Release|x86.Build.0 = Release|Win32 |
||||
{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Debug|x86.ActiveCfg = Debug|Win32 |
||||
{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Debug|x86.Build.0 = Debug|Win32 |
||||
{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Release|x86.ActiveCfg = Release|Win32 |
||||
{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}.Release|x86.Build.0 = Release|Win32 |
||||
{B28F69CE-15A1-424D-BBB5-2727258D675B}.Debug|x86.ActiveCfg = Debug|Win32 |
||||
{B28F69CE-15A1-424D-BBB5-2727258D675B}.Debug|x86.Build.0 = Debug|Win32 |
||||
{B28F69CE-15A1-424D-BBB5-2727258D675B}.Release|x86.ActiveCfg = Release|Win32 |
||||
{B28F69CE-15A1-424D-BBB5-2727258D675B}.Release|x86.Build.0 = Release|Win32 |
||||
EndGlobalSection |
||||
GlobalSection(SolutionProperties) = preSolution |
||||
HideSolutionNode = FALSE |
||||
EndGlobalSection |
||||
GlobalSection(ExtensibilityGlobals) = postSolution |
||||
SolutionGuid = {6252549D-BED6-405B-9D6D-42C9074D0684} |
||||
EndGlobalSection |
||||
EndGlobal |
||||
@ -0,0 +1,293 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup Label="ProjectConfigurations"> |
||||
<ProjectConfiguration Include="Debug|Win32"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|Win32"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
</ItemGroup> |
||||
<PropertyGroup Label="Globals"> |
||||
<SccProjectName /> |
||||
<SccLocalPath /> |
||||
<ProjectGuid>{23114A83-7D81-4F17-A6B8-2FC51F3D72F2}</ProjectGuid> |
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
<ConfigurationType>Application</ConfigurationType> |
||||
<PlatformToolset>v141</PlatformToolset> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
<ConfigurationType>Application</ConfigurationType> |
||||
<PlatformToolset>v141</PlatformToolset> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
<ImportGroup Label="ExtensionSettings"> |
||||
</ImportGroup> |
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> |
||||
</ImportGroup> |
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> |
||||
</ImportGroup> |
||||
<PropertyGroup Label="UserMacros" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<OutDir>.\Source/WinRel\</OutDir> |
||||
<IntDir>.\Source/WinRel\</IntDir> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<OutDir>.\Source/WinDebug\</OutDir> |
||||
<IntDir>.\Source/WinDebug\</IntDir> |
||||
</PropertyGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<ClCompile> |
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion> |
||||
<StringPooling>true</StringPooling> |
||||
<Optimization>MaxSpeed</Optimization> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<AssemblerListingLocation>.\Source/WinRel\</AssemblerListingLocation> |
||||
<ObjectFileName>.\Source/WinRel\</ObjectFileName> |
||||
<ProgramDataBaseFileName>.\Source/WinRel\</ProgramDataBaseFileName> |
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings> |
||||
<MinimalRebuild>true</MinimalRebuild> |
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation> |
||||
</ClCompile> |
||||
<Midl> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<TypeLibraryName>.\Source/WinRel\Diablo.tlb</TypeLibraryName> |
||||
<MkTypLibCompatible>true</MkTypLibCompatible> |
||||
<RedirectOutputAndErrors>NUL</RedirectOutputAndErrors> |
||||
<TargetEnvironment>Win32</TargetEnvironment> |
||||
</Midl> |
||||
<ResourceCompile> |
||||
<Culture>0x0409</Culture> |
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
</ResourceCompile> |
||||
<Bscmake> |
||||
<OutputFile>.\Source/WinRel\Diablo.bsc</OutputFile> |
||||
</Bscmake> |
||||
<Link> |
||||
<SubSystem>Windows</SubSystem> |
||||
<OutputFile>.\Source/WinRel\Diablo.exe</OutputFile> |
||||
<AdditionalDependencies>DiabloUI/WinRel/DiabloUI.lib;3rdParty/Storm/Source/WinRel/Storm.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies> |
||||
<DataExecutionPrevention>false</DataExecutionPrevention> |
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<ClCompile> |
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> |
||||
<Optimization>Disabled</Optimization> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat> |
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<AssemblerListingLocation>.\Source/WinDebug\</AssemblerListingLocation> |
||||
<ObjectFileName>.\Source/WinDebug\</ObjectFileName> |
||||
<ProgramDataBaseFileName>.\Source/WinDebug\</ProgramDataBaseFileName> |
||||
<DisableSpecificWarnings>4996</DisableSpecificWarnings> |
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation> |
||||
</ClCompile> |
||||
<Midl> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<TypeLibraryName>.\Source/WinDebug\Diablo.tlb</TypeLibraryName> |
||||
<MkTypLibCompatible>true</MkTypLibCompatible> |
||||
<RedirectOutputAndErrors>NUL</RedirectOutputAndErrors> |
||||
<TargetEnvironment>Win32</TargetEnvironment> |
||||
</Midl> |
||||
<ResourceCompile> |
||||
<Culture>0x0409</Culture> |
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
</ResourceCompile> |
||||
<Bscmake> |
||||
<OutputFile>.\Source/WinDebug\Diablo.bsc</OutputFile> |
||||
</Bscmake> |
||||
<Link> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
<SubSystem>Windows</SubSystem> |
||||
<OutputFile>.\Source/WinDebug\Diablo.exe</OutputFile> |
||||
<AdditionalDependencies>DiabloUI/WinDebug/DiabloUI.lib;3rdParty/Storm/Source/WinDebug/Storm.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies> |
||||
<DataExecutionPrevention>false</DataExecutionPrevention> |
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemGroup> |
||||
<ClCompile Include="3rdParty\PKWare\explode.cpp" /> |
||||
<ClCompile Include="3rdParty\PKWare\implode.cpp" /> |
||||
<ClCompile Include="Source\appfat.cpp" /> |
||||
<ClCompile Include="Source\automap.cpp" /> |
||||
<ClCompile Include="Source\capture.cpp" /> |
||||
<ClCompile Include="Source\codec.cpp" /> |
||||
<ClCompile Include="Source\control.cpp" /> |
||||
<ClCompile Include="Source\cursor.cpp" /> |
||||
<ClCompile Include="Source\dead.cpp" /> |
||||
<ClCompile Include="Source\debug.cpp" /> |
||||
<ClCompile Include="Source\diablo.cpp" /> |
||||
<ClCompile Include="Source\doom.cpp" /> |
||||
<ClCompile Include="Source\drlg_l1.cpp" /> |
||||
<ClCompile Include="Source\drlg_l2.cpp" /> |
||||
<ClCompile Include="Source\drlg_l3.cpp" /> |
||||
<ClCompile Include="Source\drlg_l4.cpp" /> |
||||
<ClCompile Include="Source\dthread.cpp" /> |
||||
<ClCompile Include="Source\dx.cpp" /> |
||||
<ClCompile Include="Source\effects.cpp" /> |
||||
<ClCompile Include="Source\encrypt.cpp" /> |
||||
<ClCompile Include="Source\engine.cpp" /> |
||||
<ClCompile Include="Source\error.cpp" /> |
||||
<ClCompile Include="Source\fault.cpp" /> |
||||
<ClCompile Include="Source\gamemenu.cpp" /> |
||||
<ClCompile Include="Source\gendung.cpp" /> |
||||
<ClCompile Include="Source\gmenu.cpp" /> |
||||
<ClCompile Include="Source\help.cpp" /> |
||||
<ClCompile Include="Source\init.cpp" /> |
||||
<ClCompile Include="Source\interfac.cpp" /> |
||||
<ClCompile Include="Source\inv.cpp" /> |
||||
<ClCompile Include="Source\items.cpp" /> |
||||
<ClCompile Include="Source\lighting.cpp" /> |
||||
<ClCompile Include="Source\loadsave.cpp" /> |
||||
<ClCompile Include="Source\logging.cpp" /> |
||||
<ClCompile Include="Source\mainmenu.cpp" /> |
||||
<ClCompile Include="Source\minitext.cpp" /> |
||||
<ClCompile Include="Source\missiles.cpp" /> |
||||
<ClCompile Include="Source\monster.cpp" /> |
||||
<ClCompile Include="Source\movie.cpp" /> |
||||
<ClCompile Include="Source\mpqapi.cpp" /> |
||||
<ClCompile Include="Source\msg.cpp" /> |
||||
<ClCompile Include="Source\msgcmd.cpp" /> |
||||
<ClCompile Include="Source\multi.cpp" /> |
||||
<ClCompile Include="Source\nthread.cpp" /> |
||||
<ClCompile Include="Source\objects.cpp" /> |
||||
<ClCompile Include="Source\pack.cpp" /> |
||||
<ClCompile Include="Source\palette.cpp" /> |
||||
<ClCompile Include="Source\path.cpp" /> |
||||
<ClCompile Include="Source\pfile.cpp" /> |
||||
<ClCompile Include="Source\player.cpp" /> |
||||
<ClCompile Include="Source\plrmsg.cpp" /> |
||||
<ClCompile Include="Source\portal.cpp" /> |
||||
<ClCompile Include="Source\quests.cpp" /> |
||||
<ClCompile Include="Source\restrict.cpp" /> |
||||
<ClCompile Include="Source\scrollrt.cpp" /> |
||||
<ClCompile Include="Source\setmaps.cpp" /> |
||||
<ClCompile Include="Source\sha.cpp" /> |
||||
<ClCompile Include="Source\sound.cpp" /> |
||||
<ClCompile Include="Source\spells.cpp" /> |
||||
<ClCompile Include="Source\stores.cpp" /> |
||||
<ClCompile Include="Source\sync.cpp" /> |
||||
<ClCompile Include="Source\textdat.cpp" /> |
||||
<ClCompile Include="Source\themes.cpp" /> |
||||
<ClCompile Include="Source\tmsg.cpp" /> |
||||
<ClCompile Include="Source\town.cpp" /> |
||||
<ClCompile Include="Source\towners.cpp" /> |
||||
<ClCompile Include="Source\track.cpp" /> |
||||
<ClCompile Include="Source\trigs.cpp" /> |
||||
<ClCompile Include="Source\wave.cpp" /> |
||||
<ClCompile Include="Source\render.cpp" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Image Include="Diablo.ico" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ResourceCompile Include="Diablo.rc" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ClInclude Include="3rdParty\PKWare\pkware.h" /> |
||||
<ClInclude Include="defs.h" /> |
||||
<ClInclude Include="enums.h" /> |
||||
<ClInclude Include="resource.h" /> |
||||
<ClInclude Include="Source\appfat.h" /> |
||||
<ClInclude Include="Source\automap.h" /> |
||||
<ClInclude Include="Source\capture.h" /> |
||||
<ClInclude Include="Source\codec.h" /> |
||||
<ClInclude Include="Source\control.h" /> |
||||
<ClInclude Include="Source\cursor.h" /> |
||||
<ClInclude Include="Source\dead.h" /> |
||||
<ClInclude Include="Source\debug.h" /> |
||||
<ClInclude Include="Source\diablo.h" /> |
||||
<ClInclude Include="Source\doom.h" /> |
||||
<ClInclude Include="Source\drlg_l1.h" /> |
||||
<ClInclude Include="Source\drlg_l2.h" /> |
||||
<ClInclude Include="Source\drlg_l3.h" /> |
||||
<ClInclude Include="Source\drlg_l4.h" /> |
||||
<ClInclude Include="Source\dthread.h" /> |
||||
<ClInclude Include="Source\dx.h" /> |
||||
<ClInclude Include="Source\effects.h" /> |
||||
<ClInclude Include="Source\encrypt.h" /> |
||||
<ClInclude Include="Source\engine.h" /> |
||||
<ClInclude Include="Source\error.h" /> |
||||
<ClInclude Include="Source\fault.h" /> |
||||
<ClInclude Include="Source\gamemenu.h" /> |
||||
<ClInclude Include="Source\gendung.h" /> |
||||
<ClInclude Include="Source\gmenu.h" /> |
||||
<ClInclude Include="Source\help.h" /> |
||||
<ClInclude Include="Source\init.h" /> |
||||
<ClInclude Include="Source\interfac.h" /> |
||||
<ClInclude Include="Source\inv.h" /> |
||||
<ClInclude Include="Source\items.h" /> |
||||
<ClInclude Include="Source\lighting.h" /> |
||||
<ClInclude Include="Source\loadsave.h" /> |
||||
<ClInclude Include="Source\logging.h" /> |
||||
<ClInclude Include="Source\mainmenu.h" /> |
||||
<ClInclude Include="Source\minitext.h" /> |
||||
<ClInclude Include="Source\missiles.h" /> |
||||
<ClInclude Include="Source\monster.h" /> |
||||
<ClInclude Include="Source\movie.h" /> |
||||
<ClInclude Include="Source\mpqapi.h" /> |
||||
<ClInclude Include="Source\msg.h" /> |
||||
<ClInclude Include="Source\msgcmd.h" /> |
||||
<ClInclude Include="Source\multi.h" /> |
||||
<ClInclude Include="Source\nthread.h" /> |
||||
<ClInclude Include="Source\objects.h" /> |
||||
<ClInclude Include="Source\pack.h" /> |
||||
<ClInclude Include="Source\palette.h" /> |
||||
<ClInclude Include="Source\path.h" /> |
||||
<ClInclude Include="Source\pfile.h" /> |
||||
<ClInclude Include="Source\player.h" /> |
||||
<ClInclude Include="Source\plrmsg.h" /> |
||||
<ClInclude Include="Source\portal.h" /> |
||||
<ClInclude Include="Source\quests.h" /> |
||||
<ClInclude Include="Source\restrict.h" /> |
||||
<ClInclude Include="Source\scrollrt.h" /> |
||||
<ClInclude Include="Source\setmaps.h" /> |
||||
<ClInclude Include="Source\sha.h" /> |
||||
<ClInclude Include="Source\sound.h" /> |
||||
<ClInclude Include="Source\spells.h" /> |
||||
<ClInclude Include="Source\stores.h" /> |
||||
<ClInclude Include="Source\sync.h" /> |
||||
<ClInclude Include="Source\textdat.h" /> |
||||
<ClInclude Include="Source\themes.h" /> |
||||
<ClInclude Include="Source\tmsg.h" /> |
||||
<ClInclude Include="Source\town.h" /> |
||||
<ClInclude Include="Source\towners.h" /> |
||||
<ClInclude Include="Source\track.h" /> |
||||
<ClInclude Include="Source\trigs.h" /> |
||||
<ClInclude Include="Source\wave.h" /> |
||||
<ClInclude Include="Source\render.h" /> |
||||
<ClInclude Include="structs.h" /> |
||||
<ClInclude Include="types.h" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ProjectReference Include="3rdParty\Storm\Source\Storm.vcxproj"> |
||||
<Project>{b28f69ce-15a1-424d-bbb5-2727258d675b}</Project> |
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly> |
||||
</ProjectReference> |
||||
<ProjectReference Include="DiabloUI\DiabloUI.vcxproj"> |
||||
<Project>{8408e35e-3cf5-4d4e-b873-af3952cdabd4}</Project> |
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly> |
||||
</ProjectReference> |
||||
</ItemGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
<ImportGroup Label="ExtensionTargets"> |
||||
</ImportGroup> |
||||
</Project> |
||||
@ -0,0 +1,467 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup> |
||||
<Filter Include="Source Files"> |
||||
<UniqueIdentifier>{0fb229f0-d459-4ec9-b897-317b016e0a57}</UniqueIdentifier> |
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions> |
||||
</Filter> |
||||
<Filter Include="Resource Files"> |
||||
<UniqueIdentifier>{52f34be1-947a-42ee-b303-4a46566a14a7}</UniqueIdentifier> |
||||
<Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions> |
||||
</Filter> |
||||
<Filter Include="Header Files"> |
||||
<UniqueIdentifier>{8003aed2-27a6-444b-8fb0-bb8a59530005}</UniqueIdentifier> |
||||
<Extensions>h;hpp;hxx;hm;inl</Extensions> |
||||
</Filter> |
||||
<Filter Include="PKWare"> |
||||
<UniqueIdentifier>{5dbacde9-4fc8-4776-ba59-92912e0c8ab5}</UniqueIdentifier> |
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions> |
||||
</Filter> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ClCompile Include="Source\appfat.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\automap.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\capture.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\codec.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\control.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\cursor.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\dead.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\debug.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\diablo.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\doom.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\drlg_l1.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\drlg_l2.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\drlg_l3.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\drlg_l4.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\dthread.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\dx.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\effects.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\encrypt.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\engine.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\error.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\fault.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\gamemenu.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\gendung.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\gmenu.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\help.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\init.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\interfac.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\inv.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\items.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\lighting.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\loadsave.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\logging.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\mainmenu.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\minitext.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\missiles.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\monster.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\movie.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\mpqapi.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\msg.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\msgcmd.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\multi.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\nthread.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\objects.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\pack.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\palette.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\path.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\pfile.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\player.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\plrmsg.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\portal.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\quests.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\restrict.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\scrollrt.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\setmaps.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\sha.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\sound.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\spells.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\stores.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\sync.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\textdat.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\themes.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\tmsg.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\town.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\towners.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\track.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\trigs.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\wave.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="Source\render.cpp"> |
||||
<Filter>Source Files</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="3rdParty\PKWare\explode.cpp"> |
||||
<Filter>PKWare</Filter> |
||||
</ClCompile> |
||||
<ClCompile Include="3rdParty\PKWare\implode.cpp"> |
||||
<Filter>PKWare</Filter> |
||||
</ClCompile> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<Image Include="Diablo.ico"> |
||||
<Filter>Resource Files</Filter> |
||||
</Image> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ResourceCompile Include="Diablo.rc"> |
||||
<Filter>Resource Files</Filter> |
||||
</ResourceCompile> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ClInclude Include="resource.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\appfat.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\automap.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\capture.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\codec.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\control.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\cursor.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\dead.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\debug.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\diablo.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\doom.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\drlg_l1.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\drlg_l2.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\drlg_l3.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\drlg_l4.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\dthread.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\dx.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\effects.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\encrypt.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\engine.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\error.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\fault.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\gamemenu.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\gendung.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\gmenu.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\help.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\init.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\interfac.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\inv.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\items.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\lighting.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\loadsave.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\logging.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\mainmenu.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\minitext.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\missiles.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\monster.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\movie.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\mpqapi.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\msg.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\msgcmd.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\multi.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\nthread.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\objects.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\pack.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\palette.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\path.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\pfile.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\player.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\plrmsg.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\portal.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\quests.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\restrict.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\scrollrt.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\setmaps.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\sha.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\sound.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\spells.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\stores.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\sync.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\textdat.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\themes.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\tmsg.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\town.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\towners.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\track.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\trigs.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\wave.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="Source\render.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="defs.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="enums.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="structs.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="types.h"> |
||||
<Filter>Header Files</Filter> |
||||
</ClInclude> |
||||
<ClInclude Include="3rdParty\PKWare\pkware.h"> |
||||
<Filter>PKWare</Filter> |
||||
</ClInclude> |
||||
</ItemGroup> |
||||
</Project> |
||||
@ -0,0 +1,93 @@
|
||||
# Microsoft Developer Studio Project File - Name="DiabloUI" - Package Owner=<4> |
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
||||
# ** DO NOT EDIT ** |
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 |
||||
|
||||
CFG=DiabloUI - Win32 Debug |
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
||||
!MESSAGE use the Export Makefile command and run |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "DiabloUI.mak". |
||||
!MESSAGE |
||||
!MESSAGE You can specify a configuration when running NMAKE |
||||
!MESSAGE by defining the macro CFG on the command line. For example: |
||||
!MESSAGE |
||||
!MESSAGE NMAKE /f "DiabloUI.mak" CFG="DiabloUI - Win32 Debug" |
||||
!MESSAGE |
||||
!MESSAGE Possible choices for configuration are: |
||||
!MESSAGE |
||||
!MESSAGE "DiabloUI - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") |
||||
!MESSAGE "DiabloUI - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") |
||||
!MESSAGE |
||||
|
||||
# Begin Project |
||||
# PROP AllowPerConfigDependencies 0 |
||||
# PROP Scc_ProjName "" |
||||
# PROP Scc_LocalPath "" |
||||
CPP=cl.exe |
||||
MTL=midl.exe |
||||
RSC=rc.exe |
||||
|
||||
!IF "$(CFG)" == "DiabloUI - Win32 Release" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 0 |
||||
# PROP BASE Output_Dir "WinRel" |
||||
# PROP BASE Intermediate_Dir "WinRel" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 0 |
||||
# PROP Output_Dir "WinRel" |
||||
# PROP Intermediate_Dir "WinRel" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG" |
||||
# ADD RSC /l 0x409 /d "NDEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 |
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /def:"diabloui.def" |
||||
|
||||
!ELSEIF "$(CFG)" == "DiabloUI - Win32 Debug" |
||||
|
||||
# PROP BASE Use_MFC 0 |
||||
# PROP BASE Use_Debug_Libraries 1 |
||||
# PROP BASE Output_Dir "WinDebug" |
||||
# PROP BASE Intermediate_Dir "WinDebug" |
||||
# PROP BASE Target_Dir "" |
||||
# PROP Use_MFC 0 |
||||
# PROP Use_Debug_Libraries 1 |
||||
# PROP Output_Dir "WinDebug" |
||||
# PROP Intermediate_Dir "WinDebug" |
||||
# PROP Target_Dir "" |
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /O1 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c |
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 |
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG" |
||||
# ADD RSC /l 0x409 /d "_DEBUG" |
||||
BSC32=bscmake.exe |
||||
# ADD BASE BSC32 /nologo |
||||
# ADD BSC32 /nologo |
||||
LINK32=link.exe |
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept |
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:"diabloui.def" /pdbtype:sept |
||||
|
||||
!ENDIF |
||||
|
||||
# Begin Target |
||||
|
||||
# Name "DiabloUI - Win32 Release" |
||||
# Name "DiabloUI - Win32 Debug" |
||||
# Begin Source File |
||||
|
||||
SOURCE=.\diabloui.cpp |
||||
# End Source File |
||||
# End Target |
||||
# End Project |
||||
@ -0,0 +1,146 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup Label="ProjectConfigurations"> |
||||
<ProjectConfiguration Include="Debug|Win32"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|Win32"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
</ItemGroup> |
||||
<PropertyGroup Label="Globals"> |
||||
<SccProjectName /> |
||||
<SccLocalPath /> |
||||
<ProjectGuid>{8408E35E-3CF5-4D4E-B873-AF3952CDABD4}</ProjectGuid> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
<PlatformToolset>v141</PlatformToolset> |
||||
<UseOfMfc>false</UseOfMfc> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
<ConfigurationType>DynamicLibrary</ConfigurationType> |
||||
<PlatformToolset>v141</PlatformToolset> |
||||
<UseOfMfc>false</UseOfMfc> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
<ImportGroup Label="ExtensionSettings"> |
||||
</ImportGroup> |
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> |
||||
</ImportGroup> |
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
<Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" /> |
||||
</ImportGroup> |
||||
<PropertyGroup Label="UserMacros" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<OutDir>.\WinRel\</OutDir> |
||||
<IntDir>.\WinRel\</IntDir> |
||||
<LinkIncremental>false</LinkIncremental> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<OutDir>.\WinDebug\</OutDir> |
||||
<IntDir>.\WinDebug\</IntDir> |
||||
<LinkIncremental>true</LinkIncremental> |
||||
</PropertyGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<ClCompile> |
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion> |
||||
<StringPooling>true</StringPooling> |
||||
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
<Optimization>MaxSpeed</Optimization> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<AssemblerListingLocation>.\WinRel\</AssemblerListingLocation> |
||||
<PrecompiledHeaderOutputFile>.\WinRel\DiabloUI.pch</PrecompiledHeaderOutputFile> |
||||
<ObjectFileName>.\WinRel\</ObjectFileName> |
||||
<ProgramDataBaseFileName>.\WinRel\</ProgramDataBaseFileName> |
||||
</ClCompile> |
||||
<Midl> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<TypeLibraryName>.\WinRel\DiabloUI.tlb</TypeLibraryName> |
||||
<MkTypLibCompatible>true</MkTypLibCompatible> |
||||
<RedirectOutputAndErrors>NUL</RedirectOutputAndErrors> |
||||
<TargetEnvironment>Win32</TargetEnvironment> |
||||
</Midl> |
||||
<ResourceCompile> |
||||
<Culture>0x0409</Culture> |
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
</ResourceCompile> |
||||
<Bscmake> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<OutputFile>.\WinRel\DiabloUI.bsc</OutputFile> |
||||
</Bscmake> |
||||
<Link> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<LinkDLL>true</LinkDLL> |
||||
<SubSystem>Windows</SubSystem> |
||||
<ModuleDefinitionFile>diabloui.def</ModuleDefinitionFile> |
||||
<OutputFile>.\WinRel\DiabloUI.dll</OutputFile> |
||||
<ImportLibrary>.\WinRel\DiabloUI.lib</ImportLibrary> |
||||
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<ClCompile> |
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> |
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion> |
||||
<Optimization>Disabled</Optimization> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<MinimalRebuild>true</MinimalRebuild> |
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat> |
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<AssemblerListingLocation>.\WinDebug\</AssemblerListingLocation> |
||||
<PrecompiledHeaderOutputFile>.\WinDebug\DiabloUI.pch</PrecompiledHeaderOutputFile> |
||||
<ObjectFileName>.\WinDebug\</ObjectFileName> |
||||
<ProgramDataBaseFileName>.\WinDebug\</ProgramDataBaseFileName> |
||||
</ClCompile> |
||||
<Midl> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<TypeLibraryName>.\WinDebug\DiabloUI.tlb</TypeLibraryName> |
||||
<MkTypLibCompatible>true</MkTypLibCompatible> |
||||
<RedirectOutputAndErrors>NUL</RedirectOutputAndErrors> |
||||
<TargetEnvironment>Win32</TargetEnvironment> |
||||
</Midl> |
||||
<ResourceCompile> |
||||
<Culture>0x0409</Culture> |
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
</ResourceCompile> |
||||
<Bscmake> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<OutputFile>.\WinDebug\DiabloUI.bsc</OutputFile> |
||||
</Bscmake> |
||||
<Link> |
||||
<SuppressStartupBanner>true</SuppressStartupBanner> |
||||
<LinkDLL>true</LinkDLL> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
<SubSystem>Windows</SubSystem> |
||||
<ModuleDefinitionFile>diabloui.def</ModuleDefinitionFile> |
||||
<OutputFile>.\WinDebug\DiabloUI.dll</OutputFile> |
||||
<ImportLibrary>.\WinDebug\DiabloUI.lib</ImportLibrary> |
||||
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemGroup> |
||||
<ClCompile Include="diabloui.cpp" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<None Include="diabloui.def" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ClInclude Include="diabloui.h" /> |
||||
</ItemGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
<ImportGroup Label="ExtensionTargets"> |
||||
</ImportGroup> |
||||
</Project> |
||||
@ -0,0 +1,61 @@
|
||||
#include <windows.h> |
||||
#include <stdio.h> |
||||
#include <ddraw.h> |
||||
#include <dsound.h> |
||||
#include <io.h> |
||||
#include <math.h> |
||||
#include <time.h> |
||||
#include <process.h> |
||||
#include <shlobj.h> |
||||
|
||||
#ifdef _MSC_VER |
||||
#pragma warning (disable : 4018) // signed/unsigned mismatch
|
||||
#endif |
||||
|
||||
#include "..\defs.h" |
||||
#include "..\enums.h" |
||||
#include "..\structs.h" |
||||
#include "diabloui.h" |
||||
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved |
||||
) |
||||
{ |
||||
switch (ul_reason_for_call) |
||||
{ |
||||
case DLL_PROCESS_ATTACH: |
||||
case DLL_THREAD_ATTACH: |
||||
case DLL_THREAD_DETACH: |
||||
case DLL_PROCESS_DETACH: |
||||
break; |
||||
} |
||||
return TRUE; |
||||
} |
||||
|
||||
void __cdecl UiDestroy() { return; } |
||||
void __stdcall UiTitleDialog(int a1) { return; } |
||||
void __cdecl UiInitialize() { return; } |
||||
void __stdcall UiCopyProtError(int a1) { return; } |
||||
void __stdcall UiAppActivate(int a1) { return; } |
||||
int __stdcall UiValidPlayerName(char *a1) { return 0; } |
||||
int __stdcall UiSelHeroMultDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, int *a6, char *name) { return 0; } |
||||
int __stdcall UiSelHeroSingDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, char *name, int *difficulty) { return 0; } |
||||
void __stdcall UiCreditsDialog(int a1) { return; } |
||||
int __stdcall UiMainMenuDialog(char *name, int *a2, void *fnSound, int a4) { return 0; } |
||||
int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5) { return 0; } |
||||
int __cdecl UiProfileGetString() { return 0; } |
||||
void __cdecl UiProfileCallback() { return; } |
||||
void __cdecl UiProfileDraw() { return; } |
||||
void __cdecl UiCategoryCallback() { return; } |
||||
void __cdecl UiGetDataCallback() { return; } |
||||
void __cdecl UiAuthCallback() { return; } |
||||
void __cdecl UiSoundCallback() { return; } |
||||
void __cdecl UiMessageBoxCallback() { return; } |
||||
void __cdecl UiDrawDescCallback() { return; } |
||||
void __cdecl UiCreateGameCallback() { return; } |
||||
void __cdecl UiArtCallback() { return; } |
||||
int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *a6) { return 0; } |
||||
int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *type) { return 0; } |
||||
int __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc) { return 0; } |
||||
int __stdcall UiSetupPlayerInfo(char *str, _uiheroinfo *info, int mode) { return 0; } |
||||
@ -0,0 +1,29 @@
|
||||
LIBRARY "DiabloUI" |
||||
|
||||
EXPORTS |
||||
UiDestroy |
||||
UiTitleDialog |
||||
UiInitialize |
||||
UiCopyProtError |
||||
UiAppActivate |
||||
UiValidPlayerName |
||||
UiSelHeroMultDialog |
||||
UiSelHeroSingDialog |
||||
UiCreditsDialog |
||||
UiMainMenuDialog |
||||
UiProgressDialog |
||||
UiProfileGetString |
||||
UiProfileCallback |
||||
UiProfileDraw |
||||
UiCategoryCallback |
||||
UiGetDataCallback |
||||
UiAuthCallback |
||||
UiSoundCallback |
||||
UiMessageBoxCallback |
||||
UiDrawDescCallback |
||||
UiCreateGameCallback |
||||
UiArtCallback |
||||
UiSelectGame |
||||
UiSelectProvider |
||||
UiCreatePlayerDescription |
||||
UiSetupPlayerInfo |
||||
@ -0,0 +1,40 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DIABLOUI_H__ |
||||
#define __DIABLOUI_H__ |
||||
|
||||
#ifdef __GNUC__ |
||||
extern "C" { |
||||
#endif |
||||
|
||||
void __cdecl UiDestroy(); |
||||
void __stdcall UiTitleDialog(int a1); |
||||
void __cdecl UiInitialize(); |
||||
void __stdcall UiCopyProtError(int a1); |
||||
void __stdcall UiAppActivate(int a1); |
||||
int __stdcall UiValidPlayerName(char *a1); |
||||
int __stdcall UiSelHeroMultDialog(void *fninfo, void *fncreate, void *fnremove, void *fnstats, int *a5, int *a6, char *name); |
||||
int __stdcall UiSelHeroSingDialog(void (*fninfo)(void (__stdcall *ui_add_hero_info)(_uiheroinfo *)), void (*fncreate)(_uiheroinfo *heroinfo), void (*fnremove)(), void (*fnstats)(), int *a5, char *name, int *difficulty); |
||||
void __stdcall UiCreditsDialog(int a1); |
||||
int __stdcall UiMainMenuDialog(char *name, int *a2, void *fnSound, int a4); |
||||
int __stdcall UiProgressDialog(HWND window, char *msg, int a3, void *fnfunc, int a5); |
||||
int __cdecl UiProfileGetString(); |
||||
void __cdecl UiProfileCallback(); |
||||
void __cdecl UiProfileDraw(); |
||||
void __cdecl UiCategoryCallback(); |
||||
void __cdecl UiGetDataCallback(); |
||||
void __cdecl UiAuthCallback(); |
||||
void __cdecl UiSoundCallback(); |
||||
void __cdecl UiMessageBoxCallback(); |
||||
void __cdecl UiDrawDescCallback(); |
||||
void __cdecl UiCreateGameCallback(); |
||||
void __cdecl UiArtCallback(); |
||||
int __stdcall UiSelectGame(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *a6); |
||||
int __stdcall UiSelectProvider(int a1, _SNETPROGRAMDATA *client_info, _SNETPLAYERDATA *user_info, _SNETUIDATA *ui_info, _SNETVERSIONDATA *file_info, int *type); |
||||
int __stdcall UiCreatePlayerDescription(_uiheroinfo *info, int mode, char *desc); |
||||
int __stdcall UiSetupPlayerInfo(char *str, _uiheroinfo *info, int mode); |
||||
|
||||
#ifdef __GNUC__ |
||||
} |
||||
#endif |
||||
|
||||
#endif /* __DIABLOUI_H__ */ |
||||
@ -0,0 +1,48 @@
|
||||
LIBRARY "DiabloUI" |
||||
|
||||
EXPORTS |
||||
UiValidPlayerName @1 NONAME |
||||
UiValidPlayerName@4 @1 NONAME |
||||
UiAppActivate @2 NONAME |
||||
UiAppActivate@4 @2 NONAME |
||||
UiArtCallback @3 NONAME |
||||
UiAuthCallback @4 NONAME |
||||
UiBetaDisclaimer @5 NONAME |
||||
UiCategoryCallback @6 NONAME |
||||
UiCopyProtError @7 NONAME |
||||
UiCreateGameCallback @8 NONAME |
||||
UiCreateGameCriteria @9 NONAME |
||||
UiCreatePlayerDescription @10 NONAME |
||||
UiCreatePlayerDescription@12 @10 NONAME |
||||
UiCreditsDialog @11 NONAME |
||||
UiCreditsDialog@4 @11 NONAME |
||||
UiDestroy @12 NONAME |
||||
UiDrawDescCallback @13 NONAME |
||||
UiGetDataCallback @14 NONAME |
||||
UiGetDefaultStats @15 NONAME |
||||
UiInitialize @16 NONAME |
||||
UiMainMenuDialog @17 NONAME |
||||
UiMainMenuDialog@16 @17 NONAME |
||||
UiMessageBoxCallback @18 NONAME |
||||
UiOnPaint @19 NONAME |
||||
UiProfileCallback @20 NONAME |
||||
UiProfileDraw @21 NONAME |
||||
UiProfileGetString @22 NONAME |
||||
UiProgressDialog @23 NONAME |
||||
UiProgressDialog@20 @23 NONAME |
||||
UiSelHeroMultDialog @24 NONAME |
||||
UiSelHeroMultDialog@28 @24 NONAME |
||||
UiSelHeroSingDialog @25 NONAME |
||||
UiSelHeroSingDialog@28 @25 NONAME |
||||
UiSelectGame @26 NONAME |
||||
UiSelectGame@24 @26 NONAME |
||||
UiSelectProvider @27 NONAME |
||||
UiSelectProvider@24 @27 NONAME |
||||
UiSelectRegion @28 NONAME |
||||
UiSetBackgroundBitmap @29 NONAME |
||||
UiSetSpawned @30 NONAME |
||||
UiSetupPlayerInfo @31 NONAME |
||||
UiSetupPlayerInfo@12 @31 NONAME |
||||
UiSoundCallback @32 NONAME |
||||
UiTitleDialog @33 NONAME |
||||
UiTitleDialog@4 @33 NONAME |
||||
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain. |
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or |
||||
distribute this software, either in source code form or as a compiled |
||||
binary, for any purpose, commercial or non-commercial, and by any |
||||
means. |
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors |
||||
of this software dedicate any and all copyright interest in the |
||||
software to the public domain. We make this dedication for the benefit |
||||
of the public at large and to the detriment of our heirs and |
||||
successors. We intend this dedication to be an overt act of |
||||
relinquishment in perpetuity of all present and future rights to this |
||||
software under copyright law. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||||
OTHER DEALINGS IN THE SOFTWARE. |
||||
|
||||
For more information, please refer to <http://unlicense.org> |
||||
@ -0,0 +1,55 @@
|
||||
# mingw32 and mingw64 have different executables
|
||||
ifdef MINGW32 |
||||
CXX=mingw32-g++
|
||||
DLLTOOL=dlltool
|
||||
WINDRES=windres
|
||||
else |
||||
CXX=i686-w64-mingw32-g++
|
||||
DLLTOOL=i686-w64-mingw32-dlltool
|
||||
WINDRES=i686-w64-mingw32-windres
|
||||
endif |
||||
|
||||
# Clang doesn't understand permissive compilation, we need to "fix" invalid
|
||||
# casts from a pointer type there using
|
||||
# static_cast<NEW_TYPE>(reinterpret_cast<uintptr_t>(ptr))
|
||||
# instead of
|
||||
# (NEW_TYPE)(ptr)
|
||||
CXXFLAGS=-fpermissive -Wno-write-strings
|
||||
CPPFLAGS=-MMD -MF $*.d
|
||||
LDLIBS=-lgdi32 -lversion -ldiabloui -lstorm
|
||||
LDFLAGS=-L./ -static-libgcc -mwindows
|
||||
|
||||
all: devilution.exe |
||||
|
||||
debug: CXXFLAGS += -D_DEBUG |
||||
debug: CPPFLAGS += -D_DEBUG |
||||
debug: devilution.exe |
||||
|
||||
DIABLO_SRC=$(wildcard Source/*.cpp)
|
||||
OBJS=$(DIABLO_SRC:.cpp=.o)
|
||||
|
||||
PKWARE_SRC=$(wildcard 3rdParty/PKWare/*.cpp)
|
||||
PKWARE_OBJS=$(PKWARE_SRC:.cpp=.o)
|
||||
|
||||
devilution.exe: $(OBJS) $(PKWARE_OBJS) diabres.o diabloui.lib storm.lib |
||||
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
|
||||
|
||||
diabres.o: Diablo.rc |
||||
$(WINDRES) $< $@
|
||||
|
||||
diabloui.lib: diabloui.dll DiabloUI/diabloui_gcc.def |
||||
$(DLLTOOL) -d DiabloUI/diabloui_gcc.def -D $< -l $@
|
||||
|
||||
diabloui.dll: |
||||
# $(error Please copy diabloui.dll (version 1.09[b]) here)
|
||||
|
||||
storm.lib: storm.dll 3rdParty/Storm/Source/storm_gcc.def |
||||
$(DLLTOOL) -d 3rdParty/Storm/Source/storm_gcc.def -D $< -l $@
|
||||
|
||||
storm.dll: |
||||
# $(error Please copy storm.dll (version 1.09[b]) here)
|
||||
|
||||
clean: |
||||
@$(RM) -v $(OBJS) $(OBJS:.o=.d) $(PKWARE_OBJS) $(PKWARE_OBJS:.o=d) diabres.o storm.lib diabloui.lib devilution.exe
|
||||
|
||||
.PHONY: clean all |
||||
@ -0,0 +1,83 @@
|
||||
VC5_DIR ?= $(HOME)/DevStudio_5.10/VC |
||||
|
||||
# The $(VS6_DIR) directory is a copy of the "Microsoft Visual Studio" directory. |
||||
# |
||||
# To get a working setup on Linux or other "portable" copies of VS, |
||||
# the following DLLs have to be compied to the |
||||
# $(VS6_DIR)/VC98/Bin directory. |
||||
# |
||||
# - $(VS6_DIR)/Common/MSDev98/Bin/MSPDB60.DLL |
||||
VS6_DIR ?= $(HOME)/VS6 |
||||
|
||||
VC6_DIR = $(VS6_DIR)/VC98 |
||||
|
||||
VC6_BIN_DIR = $(VC6_DIR)/Bin |
||||
VC6_INC_DIR = $(VC6_DIR)/Include |
||||
VC6_LIB_DIR = $(VC6_DIR)/Lib |
||||
|
||||
VC5_LIB_DIR = $(VC5_DIR)/lib |
||||
|
||||
IDE_DIR ?= $(VS6_DIR)/Common/MSDev98 |
||||
IDE_BIN_DIR = $(IDE_DIR)/bin |
||||
ifeq ($(OS),Windows_NT) |
||||
CL = $(VC6_BIN_DIR)/CL.EXE |
||||
RC = $(IDE_BIN_DIR)/RC.EXE |
||||
VC5_LINK = $(VC5_DIR)/bin/link.exe |
||||
VC6_LINK = $(VC6_BIN_DIR)/link.exe |
||||
else |
||||
CL = wine $(VC6_BIN_DIR)/CL.EXE |
||||
RC = wine $(IDE_BIN_DIR)/RC.EXE |
||||
VC5_LINK = wine $(VC5_DIR)/bin/link.exe |
||||
VC6_LINK = wine $(VC6_BIN_DIR)/link.exe |
||||
endif |
||||
|
||||
CFLAGS=/nologo /c /GX /W3 /O1 /I $(VC6_INC_DIR) /FD /MT /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /Fp"Diablo.pch" /YX /Gm /Zi |
||||
LINKFLAGS=/nologo /subsystem:windows /machine:I386 /incremental:no |
||||
|
||||
ifeq ($(MAKE_BUILD),pdb) |
||||
VC_LINK = $(VC6_LINK) |
||||
LINKFLAGS += /pdb:"Diablo.pdb" /LIBPATH:$(VC6_LIB_DIR) /debug |
||||
else |
||||
VC_LINK=$(VC5_LINK) |
||||
LINKFLAGS+= /LIBPATH:$(VC5_LIB_DIR) |
||||
endif |
||||
|
||||
all: Diablo.exe |
||||
|
||||
# fix compilation order to match the VC6 workspace files |
||||
DIABLO_SRC=$(sort $(filter-out Source/render.cpp, $(wildcard Source/*.cpp))) |
||||
DIABLO_SRC += Source/render.cpp |
||||
OBJS=$(DIABLO_SRC:.cpp=.obj) |
||||
|
||||
PKWARE_SRC=$(sort $(wildcard 3rdParty/PKWare/*.cpp)) |
||||
PKWARE_OBJS=$(PKWARE_SRC:.cpp=.obj) |
||||
|
||||
STORM_SRC=$(sort $(wildcard 3rdParty/Storm/Source/*.cpp)) |
||||
STORM_OBJS=$(STORM_SRC:.cpp=.obj) |
||||
|
||||
DIABLOUI_SRC=$(sort $(wildcard DiabloUI/*.cpp)) |
||||
DIABLOUI_OBJS=$(DIABLOUI_SRC:.cpp=.obj) |
||||
|
||||
Diablo.exe: main_files $(PKWARE_OBJS) diablo.res DiabloUI/diabloui.lib 3rdParty/Storm/Source/storm.lib |
||||
$(VC_LINK) /OUT:$@ $(LINKFLAGS) $(OBJS) $(PKWARE_OBJS) diablo.res advapi32.lib gdi32.lib shell32.lib user32.lib version.lib DiabloUI/diabloui.lib 3rdParty/Storm/Source/storm.lib |
||||
|
||||
DiabloUI/diabloui.lib: $(DIABLOUI_OBJS) |
||||
$(CL) $^ /link /LINK50COMPAT /nologo /dll /subsystem:windows /machine:I386 /LIBPATH:$(VC6_LIB_DIR) /def:"DiabloUI/diabloui.def" /out:DiabloUI/diabloui.dll |
||||
|
||||
3rdParty/Storm/Source/storm.lib: $(STORM_OBJS) |
||||
$(CL) $^ /link /LINK50COMPAT /nologo /dll /subsystem:windows /machine:I386 /LIBPATH:$(VC6_LIB_DIR) /def:"3rdParty/Storm/Source/storm.def" /out:3rdParty/Storm/Source/storm.dll |
||||
|
||||
# compiles all main source files with once compiler call |
||||
main_files: |
||||
$(CL) $(CFLAGS) /FoSource/ $(DIABLO_SRC) |
||||
|
||||
%.obj: %.cpp |
||||
$(CL) $(CFLAGS) /Fo$@ $< |
||||
|
||||
diablo.res: Diablo.rc |
||||
$(RC) /i $(VC6_INC_DIR) /i $(VC6_DIR)/MFC/Include /l 0x409 /fo $@ $< |
||||
|
||||
clean: |
||||
@$(RM) -v $(OBJS) $(PKWARE_OBJS) $(STORM_OBJS) $(DIABLOUI_OBJS) DiabloUI/diabloui.{exp,lib,dll} 3rdParty/Storm/Source/storm.{exp,lib,dll} |
||||
|
||||
.PHONY: clean all |
||||
@ -0,0 +1,152 @@
|
||||
Devilution: [](https://travis-ci.org/diasurgical/devilution) |
||||
[](https://ci.appveyor.com/project/galaxyhaxz/devilution) |
||||
|
||||
Nightly: [](https://travis-ci.com/diasurgical/devil-nightly) |
||||
|
||||
[Discord](https://discord.gg/XEKDxHK) |
||||
|
||||
# Devilution |
||||
Diablo devolved - magic behind the 1996 computer game |
||||
|
||||
Reverse engineered by GalaXyHaXz in 2018 |
||||
|
||||
# Introduction |
||||
While most titles from Blizzard receive years of love and support, Diablo stayed in the shadows. Abandoned in favor of a sequel, it remained full of bugs and unfinished potential. The game was last patched in 2001 before being discontinued altogether, a problem I wanted to fix. I played Diablo extensively as a teenager, but as time passed it became difficult to run the game on newer hardware. The lack of many improvements found in the sequel also kept it from aging well. At first the game appeared to be a lost cause, but thankfully a little oversight in 1997 made it not so. |
||||
|
||||
With Diablo's development team moving on the source code was given to **Synergistic Software** to handle the expansion. Less known however is that it was also given to **Climax Studios** to create a PlayStation port. Now Sony has long been known for letting things slide; _especially_ in Japan. Anything from leaking prototypes to full source code and Diablo was no exception. Symbolic information was accidentally left on the Japanese port. Normally used for debugging, a symbol file contains a map of everything generated during compile time. This includes file names, functions, structures, variables, and more! To top it all off a special build is hidden on the PC release in `DIABDAT.MPQ -> D1221A.MPQ -> DIABLO.EXE`! This build contains debug tools and assert strings further giving away code information. |
||||
|
||||
After months of piecing these mistakes together, Devilution was born. I present to you a reconstructed form of Diablo's original source code! Once more shall the heroes of Sanctuary return to the depths below! |
||||
|
||||
# Purpose |
||||
Having the source code makes Diablo much easier to update and maintain. For years mod-makers had to rely on tedious code editing and memory injection. A few even went further and reversed most or all of the game. The problem is that they rarely shared their work. Usually being a one-person job, they move on with their lives due to the amount of time required or lack of interest. This brings us back to square one having to do countless hours of work all over again. Devilution aims to fix this by finally making the source code open to the community. |
||||
|
||||
In order to ensure that everything is preserved, Devilution keeps everything as it was originally designed. This goes as far as bugs and badly written code in the original game. With that it serves as a base for developers to work with making it much easier than before to update, fix, and port the game to other platforms. |
||||
|
||||
As a side goal Devilution tries to document the unused and cut content from the final game. Development of Diablo was rushed near the end--many ideas were scrapped and multiplayer was quickly hacked in. By examining the source, we can see various quirks of planned development. |
||||
|
||||
# Compiling |
||||
Diablo was developed on Windows 95 using Visual C++ 4.20 and later 5.10 and 6 for newer patches. Devilution is optimized for the same tools originally used but is also compatible with modern setups. |
||||
|
||||
### Building with Visual C++ 6 |
||||
- Open the project workspace `Diablo.dsw`, choose `Debug` or `Release`, and then `Build Diablo.exe`. |
||||
|
||||
To build a binary with functions compiled as close as possible to the original, use [Visual C++ 6](https://winworldpc.com/product/visual-c/6x) with Service Pack 5 and the [Processor Pack](https://download.microsoft.com/download/vb60ent/update/6/w9x2kxp/en-us/vcpp5.exe) (**important for proper code genration!**) |
||||
|
||||
If you aim to build a binary as close as possible to the original one you will also need [Visual C++ 5](https://winworldpc.com/product/visual-c/5x) with [Service Pack 3](http://www.mediafire.com/file/jw4j4sd5dnzze4p/VS97SP3.zip), since the original binary as linked with the older linker from that. Sadly, you cannot use the old linker right out of VC6, so you'll need to link manually or via the `MakefileVC` in the project root. |
||||
|
||||
### Building with Visual Studio 2010-2017 |
||||
- Open the project solution `Diablo.sln`, choose `Debug` or `Release`, and then `Build Solution`. |
||||
|
||||
Make sure to disable Data Execution Prevention. `Storm.dll` uses dynamic compilation to improve rendering performance but fails to mark the resulting memory page as executable, leading to a protection fault when trying to draw. |
||||
- Configuration options -> Linker -> Advanced -> Data Execution Prevention (DEP). |
||||
- Set this value to: No (/NXCOMPAT: NO). |
||||
|
||||
You will also need the following dependencies installed if you are using Visual Studio 2017. |
||||
Make sure to enable these when installing (or modify your installation): |
||||
- Requires "Windows 8.1 SDK" (Target Platform) |
||||
- Requires "Visual C++ MFC for x86 and x64" (For afxres.h) |
||||
- Requires "Windows Universal CRT SDK" (For ctype.h) |
||||
|
||||
### Building XDiablo (For Linux) |
||||
Install the following libs on your machine. |
||||
- apt-get install g++-multilib libc6-dev-i386 |
||||
- apt-get install libsdl2-dev:i386 |
||||
- apt-get install libsdl2-ttf-dev:i386 |
||||
- apt-get install libsdl2-image-dev:i386 |
||||
- apt-get install libsdl2-mixer-dev:i386 |
||||
- apt-get install cmake |
||||
|
||||
Edit File that is linking all the LIBS for CMAKE. |
||||
For me it was located in... |
||||
/usr/lib/i386-linux-gnu/cmake/SDL2/sdl2-config.cmake |
||||
|
||||
The last line will have something like... |
||||
set(SDL2_LIBRARIES "-L${SDL2_LIBDIR} -lSDL2 |
||||
Change it to ... |
||||
set(SDL2_LIBRARIES "-L${SDL2_LIBDIR} -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf ") |
||||
|
||||
|
||||
Copy the "diablodat.mpq" from your Diablo CD to the Diablo Directory and make sure it is LOWERCASE. |
||||
Copy the Xresources and fonts file to your Diablo Directory. |
||||
|
||||
|
||||
Keep in mind please that this is still being worked on and is missing parts of UI and SoundEffects are not properly playing now. |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Building with MinGW |
||||
- Execute `make MINGW32=1` for **MinGW32** or `make` for **MinGW64**. Optionally add `debug` to build with debug features. |
||||
|
||||
To compile with MinGW64 on different platforms, refer to the respective documentation: [Linux](Support/INSTALL_linux.md) | [Windows](Support/INSTALL_windows.md) | [Mac](Support/INSTALL_mac.md). |
||||
|
||||
[Debug Build Features](Support/debug.md) |
||||
| [Compatibility Matrix](Support/compatibility_matrix.md) |
||||
| [Troubleshooting](Support/troubleshooting.md) |
||||
|
||||
# Installing |
||||
Once compiled, the Devilution binary will serve as a replacement for `Diablo.exe`. The following files from the original game patched to 1.09(b) need to be present: `DIABDAT.MPQ`, `DiabloUI.dll`, `SmackW32.dll`, `Standard.snp`, and `Storm.dll`. If `COPYPROT` was defined when compiling, the Diablo CD will also be required. |
||||
|
||||
Additionally, Strange Bytes' [DirectDraw patch](http://www.strangebytes.com/index.php/projects/1-diablo-1-windows-7-vista-patch) is recommended to help fix compatibility issues and run the game in windowed mode. |
||||
|
||||
# Multiplayer |
||||
TODO |
||||
|
||||
# Contributing |
||||
[Guidelines](Support/CONTRIBUTING.md) |
||||
|
||||
# Modding |
||||
Here are some screenshots of a few things I tinkered around with, to demonstrate the relative ease of improving the game: |
||||
|
||||
 |
||||
|
||||
 |
||||
|
||||
# F.A.Q. |
||||
> Wow, does this mean I can download and play Diablo for free now? |
||||
|
||||
No, you'll need access to the data from the original game. Blizzard has discontinued Diablo, but there's plenty of used copies floating around. (I'm still using an original 1996-disc in 2018 without problems) |
||||
> Cool, so I fired your mod up, but there's no 1080p or new features? |
||||
|
||||
Devilution aims to keep the original code unaltered, for documentation purposes. |
||||
> So will you ever add cross-platform support or new features in the future? |
||||
|
||||
Yes! However, this will be a **_side project_** based on Devilution. I have yet to announce the project. |
||||
> When and what can I expect from the upcoming project? |
||||
|
||||
Honestly I have no idea. More than 1,200 hours went into creating Devilution, and I have other things going on right now. Maybe in 6-12 months? The goal is to create a native Linux port, convert to OpenGL, modernize the UI, etc. you get the drill. There has to be some surprises. ;) |
||||
> Ok, so I'm playing Devilution now and all the sudden it crashed. NOW WHAT?? |
||||
|
||||
Open an issue and provide as much information as possible (OS version, etc.) including any crash logs. |
||||
> I thought I'd fix the crash myself, but after looking at the code its a disaster. Do you speak v2-34-v8? |
||||
|
||||
That is the result of decompiled code. Whenever a program is compiled, much of the source is optimized and stripped away, so it's nearly impossible to decompile it back. Have patience. Everything will be cleaned up eventually. :) |
||||
> Will you be reverse engineering Diablo II next? Ooooh please! |
||||
|
||||
Absolutely not. Diablo II would require far more work and is still supported by Blizzard. Setting that aside, there are rumors that the game will be remastered which takes the point out of it. |
||||
> Are you interested in working for me? I have this game I want you to reverse... |
||||
|
||||
Sorry, but no. This project is time consuming enough as it is, and it's just a hobby. |
||||
> I think that's about all, but is Devilution even legal? |
||||
|
||||
That's a tricky question. Under the DMCA, reverse-engineering has exceptions for the purpose of documentation and interoperability. Devilution provides the necessary documentation needed to achieve the latter. However, it falls into an entirely gray area. The real question is whether or not Blizzard deems it necessary to take action. |
||||
|
||||
# Credits |
||||
- [sanctuary](https://github.com/sanctuary) - extensively documenting Diablo's game engine |
||||
- [BWAPI Team](https://github.com/bwapi) - providing library API to work with Storm |
||||
- [Ladislav Zezula](https://github.com/ladislav-zezula) - reversing PKWARE library, further documenting Storm |
||||
- [fearedbliss](https://github.com/fearedbliss) - being awe-inspiring |
||||
- Climax Studios & Sony - secretly helping with their undercover QA :P |
||||
- Blizzard North - wait, this was a typo! |
||||
- Depression - reason to waste four months of my life doing this ;) |
||||
|
||||
# Legal |
||||
This software is being released to the Public Domain. No assets of Diablo are being provided. You must own a copy of Diablo and have access to the assets beforehand in order to use this software. |
||||
|
||||
Battle.net(R) - Copyright (C) 1996 Blizzard Entertainment, Inc. All rights reserved. Battle.net and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment, Inc. in the U.S. and/or other countries. |
||||
|
||||
Diablo(R) - Copyright (C) 1996 Blizzard Entertainment, Inc. All rights reserved. Diablo and Blizzard Entertainment are trademarks or registered trademarks of Blizzard Entertainment, Inc. in the U.S. and/or other countries. |
||||
|
||||
This software is in no way associated with or endorsed by Blizzard Entertainment(R). |
||||
@ -0,0 +1,437 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
// +Infinity after initialization of appfat.cpp.
|
||||
float appfat_cpp_init_value; |
||||
|
||||
#ifndef NO_GLOBALS |
||||
char sz_error_buf[256]; |
||||
int terminating; // weak
|
||||
int cleanup_thread_id; // weak
|
||||
#endif |
||||
|
||||
char empty_string; |
||||
|
||||
// appfat_cpp_init initializes the C++ runtime of appfat.cpp.
|
||||
struct appfat_cpp_init { |
||||
appfat_cpp_init() { |
||||
appfat_cpp_init_value = INFINITY; |
||||
} |
||||
} appfat_cpp_init; |
||||
|
||||
// delete overloads the delete operator.
|
||||
void operator delete(void *ptr) { |
||||
if (ptr != NULL) { |
||||
SMemFree(ptr, "delete", -1, 0); |
||||
} |
||||
} |
||||
|
||||
char *__fastcall GetErrorStr(int error_code) |
||||
{ |
||||
int v1; // edi
|
||||
unsigned int v2; // eax
|
||||
signed int v4; // eax
|
||||
char *i; // ecx
|
||||
|
||||
v1 = error_code; |
||||
v2 = ((unsigned int)error_code >> 16) & 0x1FFF; |
||||
if ( v2 == 0x0878 ) |
||||
{ |
||||
TraceErrorDS(error_code, sz_error_buf, 256); |
||||
} |
||||
else if ( v2 == 0x0876 ) |
||||
{ |
||||
TraceErrorDD(error_code, sz_error_buf, 256); |
||||
} |
||||
else |
||||
{ |
||||
if ( !SErrGetErrorStr(error_code, sz_error_buf, 256) && !FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, v1, 0x400u, sz_error_buf, 0x100u, NULL) ) |
||||
wsprintf(sz_error_buf, "unknown error 0x%08x", v1); |
||||
} |
||||
v4 = strlen(sz_error_buf); |
||||
for ( i = &sz_error_buf[v4-1]; v4 > 0; *i = 0 ) |
||||
{ |
||||
--v4; |
||||
--i; |
||||
if ( *i != '\r' && *i != '\n' ) |
||||
break; |
||||
} |
||||
return sz_error_buf; |
||||
} |
||||
|
||||
#define CASE_ERROR(v, errName) case errName: v = #errName; break; |
||||
|
||||
void __fastcall TraceErrorDD(int error_code, char *error_buf, int error_buf_len) |
||||
{ |
||||
const char *v3; // eax
|
||||
char v4[20]; // [esp+0h] [ebp-14h]
|
||||
|
||||
switch (error_code) { |
||||
CASE_ERROR(v3, DDERR_CANTPAGEUNLOCK); |
||||
CASE_ERROR(v3, DDERR_NOTPAGELOCKED); |
||||
CASE_ERROR(v3, DD_OK); |
||||
CASE_ERROR(v3, DDERR_CANTPAGELOCK); |
||||
CASE_ERROR(v3, DDERR_BLTFASTCANTCLIP); |
||||
CASE_ERROR(v3, DDERR_NOBLTHW); |
||||
CASE_ERROR(v3, DDERR_NODDROPSHW); |
||||
CASE_ERROR(v3, DDERR_OVERLAYNOTVISIBLE); |
||||
CASE_ERROR(v3, DDERR_NOOVERLAYDEST); |
||||
CASE_ERROR(v3, DDERR_INVALIDPOSITION); |
||||
CASE_ERROR(v3, DDERR_NOTAOVERLAYSURFACE); |
||||
CASE_ERROR(v3, DDERR_EXCLUSIVEMODEALREADYSET); |
||||
CASE_ERROR(v3, DDERR_NOTFLIPPABLE); |
||||
CASE_ERROR(v3, DDERR_CANTDUPLICATE); |
||||
CASE_ERROR(v3, DDERR_NOTLOCKED); |
||||
CASE_ERROR(v3, DDERR_CANTCREATEDC); |
||||
CASE_ERROR(v3, DDERR_NODC); |
||||
CASE_ERROR(v3, DDERR_WRONGMODE); |
||||
CASE_ERROR(v3, DDERR_IMPLICITLYCREATED); |
||||
CASE_ERROR(v3, DDERR_NOTPALETTIZED); |
||||
CASE_ERROR(v3, DDERR_NOMIPMAPHW); |
||||
CASE_ERROR(v3, DDERR_INVALIDSURFACETYPE); |
||||
CASE_ERROR(v3, DDERR_DCALREADYCREATED); |
||||
CASE_ERROR(v3, DDERR_NOPALETTEHW); |
||||
CASE_ERROR(v3, DDERR_DIRECTDRAWALREADYCREATED); |
||||
CASE_ERROR(v3, DDERR_NODIRECTDRAWHW); |
||||
CASE_ERROR(v3, DDERR_PRIMARYSURFACEALREADYEXISTS); |
||||
CASE_ERROR(v3, DDERR_NOEMULATION); |
||||
CASE_ERROR(v3, DDERR_REGIONTOOSMALL); |
||||
CASE_ERROR(v3, DDERR_CLIPPERISUSINGHWND); |
||||
CASE_ERROR(v3, DDERR_NOCLIPPERATTACHED); |
||||
CASE_ERROR(v3, DDERR_NOHWND); |
||||
CASE_ERROR(v3, DDERR_HWNDSUBCLASSED); |
||||
CASE_ERROR(v3, DDERR_HWNDALREADYSET); |
||||
CASE_ERROR(v3, DDERR_NOPALETTEATTACHED); |
||||
CASE_ERROR(v3, DDERR_INVALIDDIRECTDRAWGUID); |
||||
CASE_ERROR(v3, DDERR_UNSUPPORTEDFORMAT); |
||||
CASE_ERROR(v3, DDERR_UNSUPPORTEDMASK); |
||||
CASE_ERROR(v3, DDERR_VERTICALBLANKINPROGRESS); |
||||
CASE_ERROR(v3, DDERR_WASSTILLDRAWING); |
||||
CASE_ERROR(v3, DDERR_XALIGN); |
||||
CASE_ERROR(v3, DDERR_TOOBIGWIDTH); |
||||
CASE_ERROR(v3, DDERR_CANTLOCKSURFACE); |
||||
CASE_ERROR(v3, DDERR_SURFACEISOBSCURED); |
||||
CASE_ERROR(v3, DDERR_SURFACELOST); |
||||
CASE_ERROR(v3, DDERR_SURFACENOTATTACHED); |
||||
CASE_ERROR(v3, DDERR_TOOBIGHEIGHT); |
||||
CASE_ERROR(v3, DDERR_TOOBIGSIZE); |
||||
CASE_ERROR(v3, DDERR_SURFACEBUSY); |
||||
CASE_ERROR(v3, DDERR_OVERLAYCOLORKEYONLYONEACTIVE); |
||||
CASE_ERROR(v3, DDERR_PALETTEBUSY); |
||||
CASE_ERROR(v3, DDERR_COLORKEYNOTSET); |
||||
CASE_ERROR(v3, DDERR_SURFACEALREADYATTACHED); |
||||
CASE_ERROR(v3, DDERR_SURFACEALREADYDEPENDENT); |
||||
CASE_ERROR(v3, DDERR_OVERLAYCANTCLIP); |
||||
CASE_ERROR(v3, DDERR_NOVSYNCHW); |
||||
CASE_ERROR(v3, DDERR_NOZBUFFERHW); |
||||
CASE_ERROR(v3, DDERR_NOZOVERLAYHW); |
||||
CASE_ERROR(v3, DDERR_OUTOFCAPS); |
||||
CASE_ERROR(v3, DDERR_OUTOFVIDEOMEMORY); |
||||
CASE_ERROR(v3, DDERR_NOTEXTUREHW); |
||||
CASE_ERROR(v3, DDERR_NOROTATIONHW); |
||||
CASE_ERROR(v3, DDERR_NOSTRETCHHW); |
||||
CASE_ERROR(v3, DDERR_NOT4BITCOLOR); |
||||
CASE_ERROR(v3, DDERR_NOT4BITCOLORINDEX); |
||||
CASE_ERROR(v3, DDERR_NOT8BITCOLOR); |
||||
CASE_ERROR(v3, DDERR_NORASTEROPHW); |
||||
CASE_ERROR(v3, DDERR_NOEXCLUSIVEMODE); |
||||
CASE_ERROR(v3, DDERR_NOFLIPHW); |
||||
CASE_ERROR(v3, DDERR_NOGDI); |
||||
CASE_ERROR(v3, DDERR_NOMIRRORHW); |
||||
CASE_ERROR(v3, DDERR_NOTFOUND); |
||||
CASE_ERROR(v3, DDERR_NOOVERLAYHW); |
||||
CASE_ERROR(v3, DDERR_NOCOLORKEYHW); |
||||
CASE_ERROR(v3, DDERR_NOALPHAHW); |
||||
CASE_ERROR(v3, DDERR_NOCLIPLIST); |
||||
CASE_ERROR(v3, DDERR_NOCOLORCONVHW); |
||||
CASE_ERROR(v3, DDERR_NOCOOPERATIVELEVELSET); |
||||
CASE_ERROR(v3, DDERR_NOCOLORKEY); |
||||
CASE_ERROR(v3, DDERR_NO3D); |
||||
CASE_ERROR(v3, DDERR_INVALIDMODE); |
||||
CASE_ERROR(v3, DDERR_INVALIDOBJECT); |
||||
CASE_ERROR(v3, DDERR_INVALIDPIXELFORMAT); |
||||
CASE_ERROR(v3, DDERR_INVALIDRECT); |
||||
CASE_ERROR(v3, DDERR_LOCKEDSURFACES); |
||||
CASE_ERROR(v3, DDERR_INVALIDCLIPLIST); |
||||
CASE_ERROR(v3, DDERR_CURRENTLYNOTAVAIL); |
||||
CASE_ERROR(v3, DDERR_EXCEPTION); |
||||
CASE_ERROR(v3, DDERR_HEIGHTALIGN); |
||||
CASE_ERROR(v3, DDERR_INCOMPATIBLEPRIMARY); |
||||
CASE_ERROR(v3, DDERR_INVALIDCAPS); |
||||
CASE_ERROR(v3, DDERR_CANNOTDETACHSURFACE); |
||||
CASE_ERROR(v3, DDERR_UNSUPPORTED); |
||||
CASE_ERROR(v3, DDERR_GENERIC); |
||||
CASE_ERROR(v3, DDERR_OUTOFMEMORY); |
||||
CASE_ERROR(v3, DDERR_INVALIDPARAMS); |
||||
CASE_ERROR(v3, DDERR_ALREADYINITIALIZED); |
||||
CASE_ERROR(v3, DDERR_CANNOTATTACHSURFACE); |
||||
default: |
||||
strcpy(v4, "DDERR unknown 0x%x"); |
||||
sprintf(error_buf, v4, error_code); |
||||
return; |
||||
} |
||||
strncpy(error_buf, v3, error_buf_len); |
||||
} |
||||
|
||||
void __fastcall TraceErrorDS(int error_code, char *error_buf, int error_buf_len) |
||||
{ |
||||
const char *v3; // eax
|
||||
char v4[20]; // [esp+0h] [ebp-14h]
|
||||
|
||||
switch (error_code) { |
||||
CASE_ERROR(v3, DSERR_PRIOLEVELNEEDED); |
||||
CASE_ERROR(v3, DSERR_BADFORMAT); |
||||
CASE_ERROR(v3, DSERR_NODRIVER); |
||||
CASE_ERROR(v3, DSERR_ALREADYINITIALIZED); |
||||
CASE_ERROR(v3, DSERR_BUFFERLOST); |
||||
CASE_ERROR(v3, DS_OK); |
||||
CASE_ERROR(v3, DSERR_INVALIDCALL); |
||||
CASE_ERROR(v3, E_NOINTERFACE); |
||||
CASE_ERROR(v3, DSERR_NOAGGREGATION); |
||||
CASE_ERROR(v3, DSERR_OUTOFMEMORY); |
||||
CASE_ERROR(v3, DSERR_INVALIDPARAM); |
||||
CASE_ERROR(v3, DSERR_ALLOCATED); |
||||
CASE_ERROR(v3, DSERR_CONTROLUNAVAIL); |
||||
default: |
||||
strcpy(v4, "DSERR unknown 0x%x"); |
||||
sprintf(error_buf, v4, error_code); |
||||
return; |
||||
} |
||||
strncpy(error_buf, v3, error_buf_len); |
||||
} |
||||
|
||||
char *__cdecl TraceLastError() |
||||
{ |
||||
int v0; // eax
|
||||
|
||||
v0 = GetLastError(); |
||||
return GetErrorStr(v0); |
||||
} |
||||
|
||||
void TermMsg(char *pszFmt, ...) |
||||
{ |
||||
va_list arglist; // [esp+8h] [ebp+8h]
|
||||
|
||||
va_start(arglist, pszFmt); |
||||
FreeDlg(); |
||||
if ( pszFmt ) |
||||
MsgBox(pszFmt, arglist); |
||||
init_cleanup(0); |
||||
exit(1); |
||||
} |
||||
|
||||
void __fastcall MsgBox(char *pszFmt, va_list va) |
||||
{ |
||||
char Text[256]; // [esp+0h] [ebp-100h]
|
||||
|
||||
wvsprintf(Text, pszFmt, va); |
||||
if ( ghMainWnd ) |
||||
SetWindowPos(ghMainWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE); |
||||
MessageBox(ghMainWnd, Text, "ERROR", MB_TASKMODAL|MB_ICONHAND); |
||||
} |
||||
|
||||
void __cdecl FreeDlg() |
||||
{ |
||||
if ( terminating && cleanup_thread_id != GetCurrentThreadId() ) |
||||
Sleep(20000u); |
||||
terminating = 1; |
||||
cleanup_thread_id = GetCurrentThreadId(); |
||||
dx_cleanup(); |
||||
if ( (unsigned char)gbMaxPlayers > 1u ) |
||||
{ |
||||
if ( SNetLeaveGame(3) ) |
||||
Sleep(2000u); |
||||
} |
||||
SNetDestroy(); |
||||
ShowCursor(1); |
||||
} |
||||
// 4B7A34: using guessed type int terminating;
|
||||
// 4B7A38: using guessed type int cleanup_thread_id;
|
||||
// 679660: using guessed type char gbMaxPlayers;
|
||||
|
||||
void DrawDlg(char *pszFmt, ...) |
||||
{ |
||||
char text[256]; // [esp+0h] [ebp-100h]
|
||||
va_list arglist; // [esp+10Ch] [ebp+Ch]
|
||||
|
||||
va_start(arglist, pszFmt); |
||||
wvsprintf(text, pszFmt, arglist); |
||||
SDrawMessageBox(text, "Diablo", MB_TASKMODAL|MB_ICONEXCLAMATION); |
||||
} |
||||
|
||||
void __fastcall DDErrMsg(int error_code, int log_line_nr, char *log_file_path) |
||||
{ |
||||
int v3; // esi
|
||||
char *v4; // eax
|
||||
|
||||
v3 = log_line_nr; |
||||
if ( error_code ) |
||||
{ |
||||
v4 = GetErrorStr(error_code); |
||||
TermMsg("Direct draw error (%s:%d)\n%s", log_file_path, v3, v4); |
||||
} |
||||
} |
||||
|
||||
void __fastcall DSErrMsg(int error_code, int log_line_nr, char *log_file_path) |
||||
{ |
||||
int v3; // esi
|
||||
char *v4; // eax
|
||||
|
||||
v3 = log_line_nr; |
||||
if ( error_code ) |
||||
{ |
||||
v4 = GetErrorStr(error_code); |
||||
TermMsg("Direct sound error (%s:%d)\n%s", log_file_path, v3, v4); |
||||
} |
||||
} |
||||
|
||||
void __fastcall center_window(HWND hDlg) |
||||
{ |
||||
LONG v1; // esi
|
||||
LONG v2; // edi
|
||||
int v3; // ebx
|
||||
char *v4; // eax
|
||||
struct tagRECT Rect; // [esp+Ch] [ebp-1Ch]
|
||||
int v6; // [esp+1Ch] [ebp-Ch]
|
||||
HDC hdc; // [esp+20h] [ebp-8h]
|
||||
HWND hWnd; // [esp+24h] [ebp-4h]
|
||||
|
||||
hWnd = hDlg; |
||||
GetWindowRect(hDlg, &Rect); |
||||
v1 = Rect.right - Rect.left; |
||||
v2 = Rect.bottom - Rect.top; |
||||
hdc = GetDC(hWnd); |
||||
v6 = GetDeviceCaps(hdc, HORZRES); |
||||
v3 = GetDeviceCaps(hdc, VERTRES); |
||||
ReleaseDC(hWnd, hdc); |
||||
if ( !SetWindowPos(hWnd, HWND_TOP, (v6 - v1) / 2, (v3 - v2) / 2, 0, 0, SWP_NOZORDER|SWP_NOSIZE) ) |
||||
{ |
||||
v4 = TraceLastError(); |
||||
TermMsg("center_window: %s", v4); |
||||
} |
||||
} |
||||
|
||||
void __fastcall ErrDlg(int template_id, int error_code, char *log_file_path, int log_line_nr) |
||||
{ |
||||
int v4; // ebx
|
||||
int v5; // edi
|
||||
char *v6; // esi
|
||||
char *v7; // eax
|
||||
char *v8; // eax
|
||||
LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h]
|
||||
|
||||
v4 = error_code; |
||||
v5 = template_id; |
||||
FreeDlg(); |
||||
v6 = log_file_path; |
||||
v7 = strrchr(log_file_path, '\\'); |
||||
if ( v7 ) |
||||
v6 = v7 + 1; |
||||
v8 = GetErrorStr(v4); |
||||
wsprintf((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v6, log_line_nr); |
||||
if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(v5), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam) == -1 ) |
||||
TermMsg("ErrDlg: %d", v5); |
||||
TermMsg(0); |
||||
} |
||||
|
||||
BOOL __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text) |
||||
{ |
||||
if ( uMsg == WM_INITDIALOG ) |
||||
{ |
||||
TextDlg(hDlg, text); |
||||
} |
||||
else |
||||
{ |
||||
if ( uMsg != WM_COMMAND ) |
||||
return 0; |
||||
if ( (_WORD)wParam == 1 ) |
||||
{ |
||||
EndDialog(hDlg, 1); |
||||
} |
||||
else if ( (_WORD)wParam == 2 ) |
||||
{ |
||||
EndDialog(hDlg, 0); |
||||
} |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
void __fastcall TextDlg(HWND hDlg, char *text) |
||||
{ |
||||
char *v2; // esi
|
||||
HWND v3; // edi
|
||||
|
||||
v2 = text; |
||||
v3 = hDlg; |
||||
center_window(hDlg); |
||||
if ( v2 ) |
||||
SetDlgItemText(v3, 1000, v2); |
||||
} |
||||
|
||||
void __fastcall ErrOkDlg(int template_id, int error_code, char *log_file_path, int log_line_nr) |
||||
{ |
||||
char *v4; // esi
|
||||
int v5; // edi
|
||||
unsigned short v6; // bx
|
||||
char *v7; // eax
|
||||
char *v8; // eax
|
||||
LPARAM dwInitParam[128]; // [esp+Ch] [ebp-200h]
|
||||
|
||||
v4 = log_file_path; |
||||
v5 = error_code; |
||||
v6 = template_id; |
||||
v7 = strrchr(log_file_path, '\\'); |
||||
if ( v7 ) |
||||
v4 = v7 + 1; |
||||
v8 = GetErrorStr(v5); |
||||
wsprintf((LPSTR)dwInitParam, "%s\nat: %s line %d", v8, v4, log_line_nr); |
||||
DialogBoxParam(ghInst, MAKEINTRESOURCE(v6), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)dwInitParam); |
||||
} |
||||
|
||||
void __fastcall FileErrDlg(char *error) |
||||
{ |
||||
char *v1; // esi
|
||||
|
||||
v1 = error; |
||||
FreeDlg(); |
||||
if ( !v1 ) |
||||
v1 = &empty_string; |
||||
if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG3), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) |
||||
TermMsg("FileErrDlg"); |
||||
TermMsg(0); |
||||
} |
||||
|
||||
void __fastcall DiskFreeDlg(char *error) |
||||
{ |
||||
char *v1; // esi
|
||||
|
||||
v1 = error; |
||||
FreeDlg(); |
||||
if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG7), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) |
||||
TermMsg("DiskFreeDlg"); |
||||
TermMsg(0); |
||||
} |
||||
|
||||
bool __cdecl InsertCDDlg() |
||||
{ |
||||
int v0; // edi
|
||||
|
||||
ShowCursor(1); |
||||
v0 = DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG9), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)&empty_string); |
||||
if ( v0 == -1 ) |
||||
TermMsg("InsertCDDlg"); |
||||
ShowCursor(0); |
||||
return v0 == 1; |
||||
} |
||||
|
||||
void __fastcall DirErrorDlg(char *error) |
||||
{ |
||||
char *v1; // esi
|
||||
|
||||
v1 = error; |
||||
FreeDlg(); |
||||
if ( DialogBoxParam(ghInst, MAKEINTRESOURCE(IDD_DIALOG11), ghMainWnd, (DLGPROC)FuncDlg, (LPARAM)v1) == -1 ) |
||||
TermMsg("DirErrorDlg"); |
||||
TermMsg(0); |
||||
} |
||||
@ -0,0 +1,30 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __APPFAT_H__ |
||||
#define __APPFAT_H__ |
||||
|
||||
extern char sz_error_buf[256]; |
||||
extern int terminating; // weak
|
||||
extern int cleanup_thread_id; // weak
|
||||
extern char empty_string; |
||||
|
||||
char *__fastcall GetErrorStr(int error_code); |
||||
void __fastcall TraceErrorDD(int error_code, char *error_buf, int error_buf_len); |
||||
void __fastcall TraceErrorDS(int error_code, char *error_buf, int error_buf_len); |
||||
char *__cdecl TraceLastError(); |
||||
void TermMsg(char *pszFmt, ...); |
||||
void __fastcall MsgBox(char *pszFmt, va_list va); |
||||
void __cdecl FreeDlg(); |
||||
void DrawDlg(char *pszFmt, ...); |
||||
void __fastcall DDErrMsg(int error_code, int log_line_nr, char *log_file_path); |
||||
void __fastcall DSErrMsg(int error_code, int log_line_nr, char *log_file_path); |
||||
void __fastcall center_window(HWND hDlg); |
||||
void __fastcall ErrDlg(int template_id, int error_code, char *log_file_path, int log_line_nr); |
||||
BOOL __stdcall FuncDlg(HWND hDlg, UINT uMsg, WPARAM wParam, char *text); |
||||
void __fastcall TextDlg(HWND hDlg, char *text); |
||||
void __fastcall ErrOkDlg(int template_id, int error_code, char *log_file_path, int log_line_nr); |
||||
void __fastcall FileErrDlg(char *error); |
||||
void __fastcall DiskFreeDlg(char *error); |
||||
bool __cdecl InsertCDDlg(); |
||||
void __fastcall DirErrorDlg(char *error); |
||||
|
||||
#endif /* __APPFAT_H__ */ |
||||
@ -0,0 +1,943 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
short automaptype[512]; |
||||
int AMdword_4B7E40; // weak
|
||||
int AMdword_4B7E44; // weak
|
||||
bool automapflag; // idb
|
||||
char AMbyte_4B7E4C[32]; |
||||
char automapview[DMAXX][DMAXY]; |
||||
int AutoMapScale; // idb
|
||||
int AutoMapXOfs; // weak
|
||||
int AutoMapYOfs; // weak
|
||||
int AutoMapPosBits; // weak
|
||||
int AutoMapXPos; // weak
|
||||
int AutoMapYPos; // weak
|
||||
int AMPlayerX; // weak
|
||||
int AMPlayerY; // weak
|
||||
#endif |
||||
|
||||
void __cdecl InitAutomapOnce() |
||||
{ |
||||
automapflag = 0; |
||||
AutoMapScale = 50; |
||||
AutoMapPosBits = 32; |
||||
AutoMapXPos = 16; |
||||
AutoMapYPos = 8; |
||||
AMPlayerX = 4; |
||||
AMPlayerY = 2; |
||||
} |
||||
// 4B84B8: using guessed type int AutoMapPosBits;
|
||||
// 4B84BC: using guessed type int AutoMapXPos;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B84C8: using guessed type int AMPlayerY;
|
||||
|
||||
void __cdecl InitAutomap() |
||||
{ |
||||
signed int v0; // edi
|
||||
signed int v1; // ecx
|
||||
int v2; // esi
|
||||
char v3; // al
|
||||
int v4; // esi
|
||||
char v5; // al
|
||||
char *v6; // ecx
|
||||
unsigned char *v7; // eax
|
||||
int v8; // ecx
|
||||
unsigned char *v9; // edx
|
||||
unsigned int i; // esi
|
||||
unsigned char v11; // bl
|
||||
_BYTE *v12; // edx
|
||||
signed int v13; // ecx
|
||||
_BYTE *v14; // eax
|
||||
signed int v15; // edx
|
||||
int size; // [esp+Ch] [ebp-4h]
|
||||
|
||||
v0 = 50; |
||||
v1 = 0; |
||||
do |
||||
{ |
||||
v2 = (v0 << 6) / 100; |
||||
v3 = 2 * (320 / v2); |
||||
v4 = 320 % v2; |
||||
v5 = v3 + 1; |
||||
AMbyte_4B7E4C[v1] = v5; |
||||
if ( v4 ) |
||||
AMbyte_4B7E4C[v1] = v5 + 1; |
||||
if ( v4 >= 32 * v0 / 100 ) |
||||
++AMbyte_4B7E4C[v1]; |
||||
v0 += 5; |
||||
++v1; |
||||
} |
||||
while ( v1 < 31 ); |
||||
memset(automaptype, 0, 0x400u); |
||||
switch ( leveltype ) |
||||
{ |
||||
case DTYPE_CATHEDRAL: |
||||
v6 = "Levels\\L1Data\\L1.AMP"; |
||||
break; |
||||
case DTYPE_CATACOMBS: |
||||
v6 = "Levels\\L2Data\\L2.AMP"; |
||||
break; |
||||
case DTYPE_CAVES: |
||||
v6 = "Levels\\L3Data\\L3.AMP"; |
||||
break; |
||||
case DTYPE_HELL: |
||||
v6 = "Levels\\L4Data\\L4.AMP"; |
||||
break; |
||||
default: |
||||
return; |
||||
} |
||||
v7 = LoadFileInMem(v6, &size); |
||||
size = (unsigned int)size >> 1; |
||||
v9 = v7; |
||||
for ( i = 1; i <= size; ++i ) |
||||
{ |
||||
v11 = *v9; |
||||
v12 = v9 + 1; |
||||
_LOWORD(v0) = v11; |
||||
_LOBYTE(v8) = *v12; |
||||
v9 = v12 + 1; |
||||
_LOWORD(v8) = (unsigned char)v8; |
||||
v8 = v0 + (v8 << 8); |
||||
automaptype[i] = v8; |
||||
} |
||||
mem_free_dbg(v7); |
||||
memset(automapview, 0, 0x640u); |
||||
v13 = 0; |
||||
do |
||||
{ |
||||
v14 = (unsigned char *)dFlags + v13; |
||||
v15 = 112; |
||||
do |
||||
{ |
||||
*v14 &= 0x7Fu; |
||||
v14 += 112; |
||||
--v15; |
||||
} |
||||
while ( v15 ); |
||||
++v13; |
||||
} |
||||
while ( v13 < 112 ); |
||||
} |
||||
// 5BB1ED: using guessed type char leveltype;
|
||||
|
||||
void __cdecl StartAutomap() |
||||
{ |
||||
AutoMapXOfs = 0; |
||||
AutoMapYOfs = 0; |
||||
automapflag = 1; |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
|
||||
void __cdecl AutomapUp() |
||||
{ |
||||
--AutoMapXOfs; |
||||
--AutoMapYOfs; |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
|
||||
void __cdecl AutomapDown() |
||||
{ |
||||
++AutoMapXOfs; |
||||
++AutoMapYOfs; |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
|
||||
void __cdecl AutomapLeft() |
||||
{ |
||||
--AutoMapXOfs; |
||||
++AutoMapYOfs; |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
|
||||
void __cdecl AutomapRight() |
||||
{ |
||||
++AutoMapXOfs; |
||||
--AutoMapYOfs; |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
|
||||
void __cdecl AutomapZoomIn() |
||||
{ |
||||
if ( AutoMapScale < 200 ) |
||||
{ |
||||
AutoMapScale += 5; |
||||
AutoMapPosBits = (AutoMapScale << 6) / 100; |
||||
AutoMapXPos = AutoMapPosBits >> 1; |
||||
AutoMapYPos = AutoMapPosBits >> 2; |
||||
AMPlayerX = AutoMapPosBits >> 3; |
||||
AMPlayerY = AutoMapPosBits >> 4; |
||||
} |
||||
} |
||||
// 4B84B8: using guessed type int AutoMapPosBits;
|
||||
// 4B84BC: using guessed type int AutoMapXPos;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B84C8: using guessed type int AMPlayerY;
|
||||
|
||||
void __cdecl AutomapZoomOut() |
||||
{ |
||||
if ( AutoMapScale > 50 ) |
||||
{ |
||||
AutoMapScale -= 5; |
||||
AutoMapPosBits = (AutoMapScale << 6) / 100; |
||||
AutoMapXPos = AutoMapPosBits >> 1; |
||||
AutoMapYPos = AutoMapPosBits >> 2; |
||||
AMPlayerX = AutoMapPosBits >> 3; |
||||
AMPlayerY = AutoMapPosBits >> 4; |
||||
} |
||||
} |
||||
// 4B84B8: using guessed type int AutoMapPosBits;
|
||||
// 4B84BC: using guessed type int AutoMapXPos;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B84C8: using guessed type int AMPlayerY;
|
||||
|
||||
void __cdecl DrawAutomap() |
||||
{ |
||||
int v0; // eax
|
||||
int v1; // ecx
|
||||
int v2; // edx
|
||||
int v3; // edx
|
||||
int v4; // ecx
|
||||
int v5; // eax
|
||||
int v6; // esi
|
||||
int v7; // edx
|
||||
int v8; // edx
|
||||
int v9; // esi
|
||||
int v10; // ebx
|
||||
int v11; // edi
|
||||
int v12; // esi
|
||||
int v13; // edi
|
||||
int v14; // esi
|
||||
int v15; // ebp
|
||||
short v16; // ax
|
||||
int v17; // ebp
|
||||
short v18; // ax
|
||||
int v19; // [esp+0h] [ebp-18h]
|
||||
int screen_x; // [esp+4h] [ebp-14h]
|
||||
int screen_xa; // [esp+4h] [ebp-14h]
|
||||
int v22; // [esp+8h] [ebp-10h]
|
||||
int ty; // [esp+Ch] [ebp-Ch]
|
||||
int tya; // [esp+Ch] [ebp-Ch]
|
||||
int v25; // [esp+10h] [ebp-8h]
|
||||
int screen_y; // [esp+14h] [ebp-4h]
|
||||
|
||||
if ( leveltype != DTYPE_TOWN ) |
||||
{ |
||||
gpBufEnd = (unsigned char *)&gpBuffer->row[352]; |
||||
v0 = AutoMapXOfs; |
||||
v1 = (ViewX - 16) >> 1; |
||||
v2 = AutoMapXOfs + v1; |
||||
if ( AutoMapXOfs + v1 < 0 ) |
||||
{ |
||||
do |
||||
{ |
||||
++v0; |
||||
++v2; |
||||
} |
||||
while ( v2 < 0 ); |
||||
AutoMapXOfs = v0; |
||||
} |
||||
v3 = v0 + v1; |
||||
if ( v0 + v1 >= 40 ) |
||||
{ |
||||
do |
||||
{ |
||||
--v0; |
||||
--v3; |
||||
} |
||||
while ( v3 >= 40 ); |
||||
AutoMapXOfs = v0; |
||||
} |
||||
v4 = v0 + v1; |
||||
AMdword_4B7E40 = v4; |
||||
v5 = AutoMapYOfs; |
||||
v6 = (ViewY - 16) >> 1; |
||||
v7 = AutoMapYOfs + v6; |
||||
if ( AutoMapYOfs + v6 < 0 ) |
||||
{ |
||||
do |
||||
{ |
||||
++v5; |
||||
++v7; |
||||
} |
||||
while ( v7 < 0 ); |
||||
AutoMapYOfs = v5; |
||||
} |
||||
v8 = v5 + v6; |
||||
if ( v5 + v6 >= 40 ) |
||||
{ |
||||
do |
||||
{ |
||||
--v5; |
||||
--v8; |
||||
} |
||||
while ( v8 >= 40 ); |
||||
AutoMapYOfs = v5; |
||||
} |
||||
v9 = v5 + v6; |
||||
AMdword_4B7E44 = v9; |
||||
v10 = AMbyte_4B7E4C[(AutoMapScale - 50) / 5]; |
||||
if ( ScrollInfo._sxoff + ScrollInfo._syoff ) |
||||
++v10; |
||||
v22 = v4 - v10; |
||||
v19 = v9 - 1; |
||||
if ( v10 & 1 ) |
||||
{ |
||||
v11 = 384 - AutoMapPosBits * ((v10 - 1) >> 1); |
||||
v12 = 336 - AutoMapXPos * ((v10 + 1) >> 1); |
||||
} |
||||
else |
||||
{ |
||||
v11 = AutoMapXPos - AutoMapPosBits * (v10 >> 1) + 384; |
||||
v12 = 336 - AutoMapXPos * (v10 >> 1) - AutoMapYPos; |
||||
} |
||||
if ( ViewX & 1 ) |
||||
{ |
||||
v11 -= AutoMapYPos; |
||||
v12 -= AMPlayerX; |
||||
} |
||||
if ( ViewY & 1 ) |
||||
{ |
||||
v11 += AutoMapYPos; |
||||
v12 -= AMPlayerX; |
||||
} |
||||
v13 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) + v11; |
||||
v14 = (AutoMapScale * ScrollInfo._syoff / 100 >> 1) + v12; |
||||
if ( invflag || sbookflag ) |
||||
v13 -= 160; |
||||
if ( chrflag || questlog ) |
||||
v13 += 160; |
||||
if ( v10 + 1 >= 0 ) |
||||
{ |
||||
v25 = v10 + 2; |
||||
do |
||||
{ |
||||
v15 = 0; |
||||
screen_x = v13; |
||||
if ( v10 > 0 ) |
||||
{ |
||||
ty = v19; |
||||
do |
||||
{ |
||||
v16 = GetAutomapType(v22 + v15, ty, 1); |
||||
if ( v16 ) |
||||
DrawAutomapType(screen_x, v14, v16); |
||||
screen_x += AutoMapPosBits; |
||||
++v15; |
||||
--ty; |
||||
} |
||||
while ( v15 < v10 ); |
||||
} |
||||
++v19; |
||||
screen_xa = 0; |
||||
v17 = v13 - AutoMapXPos; |
||||
screen_y = v14 + AutoMapYPos; |
||||
if ( v10 >= 0 ) |
||||
{ |
||||
tya = v19; |
||||
do |
||||
{ |
||||
v18 = GetAutomapType(v22 + screen_xa, tya, 1); |
||||
if ( v18 ) |
||||
DrawAutomapType(v17, screen_y, v18); |
||||
v17 += AutoMapPosBits; |
||||
++screen_xa; |
||||
--tya; |
||||
} |
||||
while ( screen_xa <= v10 ); |
||||
} |
||||
++v22; |
||||
v14 += AutoMapXPos; |
||||
--v25; |
||||
} |
||||
while ( v25 ); |
||||
} |
||||
DrawAutomapPlr(); |
||||
DrawAutomapGame(); |
||||
} |
||||
else |
||||
{ |
||||
DrawAutomapGame(); |
||||
} |
||||
} |
||||
// 4B7E40: using guessed type int AMdword_4B7E40;
|
||||
// 4B7E44: using guessed type int AMdword_4B7E44;
|
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
// 4B84B8: using guessed type int AutoMapPosBits;
|
||||
// 4B84BC: using guessed type int AutoMapXPos;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B8968: using guessed type int sbookflag;
|
||||
// 5BB1ED: using guessed type char leveltype;
|
||||
// 69BD04: using guessed type int questlog;
|
||||
// 69CF0C: using guessed type int gpBufEnd;
|
||||
|
||||
void __fastcall DrawAutomapType(int screen_x, int screen_y, short automap_type) |
||||
{ |
||||
short v3; // al
|
||||
int v4; // ebx
|
||||
int v5; // edi
|
||||
int a3; // ST2C_4
|
||||
int a1; // ST28_4
|
||||
int a2; // ST24_4
|
||||
int v9; // edx
|
||||
int v10; // ST28_4
|
||||
int v11; // ST2C_4
|
||||
int v12; // ST24_4
|
||||
int v13; // ST2C_4
|
||||
int v14; // ST28_4
|
||||
int v15; // ST24_4
|
||||
int v16; // ST28_4
|
||||
int v17; // ST24_4
|
||||
int v18; // ST2C_4
|
||||
int v19; // ST2C_4
|
||||
int v20; // ST28_4
|
||||
int v21; // ST24_4
|
||||
int v22; // ST28_4
|
||||
int v23; // ST2C_4
|
||||
int v24; // ST24_4
|
||||
int v25; // ST28_4
|
||||
int v26; // ST24_4
|
||||
int v27; // ST2C_4
|
||||
int v28; // [esp-Ch] [ebp-34h]
|
||||
int v29; // [esp-8h] [ebp-30h]
|
||||
signed int v30; // [esp+Ch] [ebp-1Ch]
|
||||
signed int v31; // [esp+10h] [ebp-18h]
|
||||
signed int v32; // [esp+14h] [ebp-14h]
|
||||
char v33; // [esp+27h] [ebp-1h]
|
||||
int automap_typea; // [esp+30h] [ebp+8h]
|
||||
int automap_typeb; // [esp+30h] [ebp+8h]
|
||||
int automap_typec; // [esp+30h] [ebp+8h]
|
||||
int automap_typed; // [esp+30h] [ebp+8h]
|
||||
int automap_typee; // [esp+30h] [ebp+8h]
|
||||
int automap_typef; // [esp+30h] [ebp+8h]
|
||||
int automap_typeg; // [esp+30h] [ebp+8h]
|
||||
|
||||
v3 = automap_type; |
||||
v4 = screen_x; |
||||
v5 = screen_y; |
||||
v33 = _HIBYTE(automap_type); |
||||
if ( automap_type & 0x4000 ) |
||||
{ |
||||
ENG_set_pixel(screen_x, screen_y, 200); |
||||
ENG_set_pixel(v4 - AMPlayerX, v5 - AMPlayerY, 200); |
||||
ENG_set_pixel(v4 - AMPlayerX, AMPlayerY + v5, 200); |
||||
ENG_set_pixel(AMPlayerX + v4, v5 - AMPlayerY, 200); |
||||
ENG_set_pixel(AMPlayerX + v4, AMPlayerY + v5, 200); |
||||
ENG_set_pixel(v4 - AutoMapYPos, v5, 200); |
||||
ENG_set_pixel(AutoMapYPos + v4, v5, 200); |
||||
ENG_set_pixel(v4, v5 - AMPlayerX, 200); |
||||
ENG_set_pixel(v4, AMPlayerX + v5, 200); |
||||
ENG_set_pixel(v4 + AMPlayerX - AutoMapXPos, AMPlayerY + v5, 200); |
||||
ENG_set_pixel(v4 + AutoMapXPos - AMPlayerX, AMPlayerY + v5, 200); |
||||
ENG_set_pixel(v4 - AutoMapYPos, AMPlayerX + v5, 200); |
||||
ENG_set_pixel(AutoMapYPos + v4, AMPlayerX + v5, 200); |
||||
ENG_set_pixel(v4 - AMPlayerX, v5 + AutoMapYPos - AMPlayerY, 200); |
||||
ENG_set_pixel(AMPlayerX + v4, v5 + AutoMapYPos - AMPlayerY, 200); |
||||
ENG_set_pixel(v4, AutoMapYPos + v5, 200); |
||||
v3 = automap_type; |
||||
} |
||||
if ( automap_type < 0 ) |
||||
{ |
||||
DrawLine(v4 - AMPlayerX, v5 - AMPlayerX - AMPlayerY, v4 + AMPlayerX + AutoMapYPos, AMPlayerY + v5, 144); |
||||
DrawLine(v4 - AutoMapYPos, v5 - AMPlayerX, AutoMapYPos + v4, AMPlayerX + v5, 144); |
||||
DrawLine(v4 - AutoMapYPos - AMPlayerX, v5 - AMPlayerY, AMPlayerX + v4, v5 + AMPlayerX + AMPlayerY, 144); |
||||
DrawLine(v4 - AutoMapXPos, v5, v4, v5 + AutoMapYPos, 144); |
||||
v3 = automap_type; |
||||
} |
||||
v31 = 0; |
||||
v30 = 0; |
||||
v32 = 0; |
||||
switch ( v3 & 0xF ) |
||||
{ |
||||
case 1: |
||||
a3 = v4 - AutoMapYPos + AutoMapXPos; |
||||
a1 = v4 - AutoMapYPos; |
||||
a2 = v5 - AutoMapYPos; |
||||
automap_typea = v5 - AMPlayerX; |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 - AutoMapYPos, v5 - AMPlayerX, 200); |
||||
DrawLine(v4, a2, a3, automap_typea, 200); |
||||
DrawLine(v4, v5, a1, automap_typea, 200); |
||||
v9 = v5; |
||||
v29 = automap_typea; |
||||
v28 = a3; |
||||
goto LABEL_36; |
||||
case 2: |
||||
case 5: |
||||
goto LABEL_8; |
||||
case 3: |
||||
case 6: |
||||
goto LABEL_17; |
||||
case 4: |
||||
v31 = 1; |
||||
goto LABEL_8; |
||||
case 7: |
||||
goto LABEL_25; |
||||
case 8: |
||||
v30 = 1; |
||||
LABEL_8: |
||||
if ( automap_type & 0x100 ) |
||||
{ |
||||
v10 = v4 - AutoMapXPos; |
||||
v11 = v4 - AutoMapYPos; |
||||
v12 = v5 - AutoMapYPos; |
||||
automap_typeb = v5 - AMPlayerX; |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 - AMPlayerX, v5 - AutoMapYPos + AMPlayerY, 200); |
||||
DrawLine(v10, v5, v10 + AMPlayerX, v5 - AMPlayerY, 200); |
||||
DrawLine(v11, v12, v10, automap_typeb, 144); |
||||
DrawLine(v11, v12, v4, automap_typeb, 144); |
||||
DrawLine(v11, v5, v10, automap_typeb, 144); |
||||
DrawLine(v11, v5, v4, automap_typeb, 144); |
||||
} |
||||
if ( v33 & 0x10 ) |
||||
{ |
||||
DrawLine(v4 - AutoMapYPos, v5 - AMPlayerX, v4 - AutoMapXPos, v5, 200); |
||||
v33 |= 4u; |
||||
} |
||||
if ( v33 & 4 ) |
||||
{ |
||||
v13 = v4 - AutoMapYPos + AutoMapXPos; |
||||
v14 = v4 - AutoMapYPos; |
||||
v15 = v5 - AutoMapYPos; |
||||
automap_typec = v5 - AMPlayerX; |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 - AutoMapYPos, v5 - AMPlayerX, 200); |
||||
DrawLine(v4, v15, v13, automap_typec, 200); |
||||
DrawLine(v4, v5, v14, automap_typec, 200); |
||||
DrawLine(v4, v5, v13, automap_typec, 200); |
||||
} |
||||
if ( !(v33 & 0x15) ) |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 - AutoMapXPos, v5, 200); |
||||
if ( v31 ) |
||||
goto LABEL_17; |
||||
goto LABEL_25; |
||||
case 9: |
||||
v32 = 1; |
||||
LABEL_17: |
||||
if ( v33 & 2 ) |
||||
{ |
||||
v16 = AutoMapYPos + v4; |
||||
v17 = v5 - AutoMapYPos; |
||||
v18 = v4 + AutoMapXPos; |
||||
automap_typed = v5 - AMPlayerX; |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 + AMPlayerX, v5 - AutoMapYPos + AMPlayerY, 200); |
||||
DrawLine(v18, v5, v18 - AMPlayerX, v5 - AMPlayerY, 200); |
||||
DrawLine(v16, v17, v4, automap_typed, 144); |
||||
DrawLine(v16, v17, v18, automap_typed, 144); |
||||
DrawLine(v16, v5, v4, automap_typed, 144); |
||||
DrawLine(v16, v5, v18, automap_typed, 144); |
||||
} |
||||
if ( v33 & 0x20 ) |
||||
{ |
||||
DrawLine(AutoMapYPos + v4, v5 - AMPlayerX, v4 + AutoMapXPos, v5, 200); |
||||
v33 |= 8u; |
||||
} |
||||
if ( v33 & 8 ) |
||||
{ |
||||
v19 = v4 - AutoMapYPos + AutoMapXPos; |
||||
v20 = v4 - AutoMapYPos; |
||||
v21 = v5 - AutoMapYPos; |
||||
automap_typee = v5 - AMPlayerX; |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 - AutoMapYPos, v5 - AMPlayerX, 200); |
||||
DrawLine(v4, v21, v19, automap_typee, 200); |
||||
DrawLine(v4, v5, v20, automap_typee, 200); |
||||
DrawLine(v4, v5, v19, automap_typee, 200); |
||||
} |
||||
if ( !(v33 & 0x2A) ) |
||||
DrawLine(v4, v5 - AutoMapYPos, v4 + AutoMapXPos, v5, 200); |
||||
LABEL_25: |
||||
if ( v30 ) |
||||
goto LABEL_26; |
||||
goto LABEL_32; |
||||
case 0xA: |
||||
goto LABEL_26; |
||||
case 0xB: |
||||
goto LABEL_33; |
||||
case 0xC: |
||||
v32 = 1; |
||||
LABEL_26: |
||||
if ( v33 & 1 ) |
||||
{ |
||||
v22 = v4 - AutoMapXPos; |
||||
v23 = v4 - AutoMapYPos; |
||||
v24 = AutoMapYPos + v5; |
||||
automap_typef = AMPlayerX + v5; |
||||
DrawLine(v4, AutoMapYPos + v5, v4 - AMPlayerX, AutoMapYPos + v5 - AMPlayerY, 200); |
||||
DrawLine(v22, v5, v22 + AMPlayerX, v5 + AMPlayerY, 200); |
||||
DrawLine(v23, v24, v22, automap_typef, 144); |
||||
DrawLine(v23, v24, v4, automap_typef, 144); |
||||
DrawLine(v23, v5, v22, automap_typef, 144); |
||||
DrawLine(v23, v5, v4, automap_typef, 144); |
||||
} |
||||
else |
||||
{ |
||||
DrawLine(v4, AutoMapYPos + v5, v4 - AutoMapXPos, v5, 200); |
||||
} |
||||
LABEL_32: |
||||
if ( v32 ) |
||||
{ |
||||
LABEL_33: |
||||
if ( v33 & 2 ) |
||||
{ |
||||
v25 = AutoMapYPos + v4; |
||||
v26 = AutoMapYPos + v5; |
||||
v27 = v4 + AutoMapXPos; |
||||
automap_typeg = AMPlayerX + v5; |
||||
DrawLine(v4, AutoMapYPos + v5, v4 + AMPlayerX, AutoMapYPos + v5 - AMPlayerY, 200); |
||||
DrawLine(v27, v5, v27 - AMPlayerX, v5 + AMPlayerY, 200); |
||||
DrawLine(v25, v26, v4, automap_typeg, 144); |
||||
DrawLine(v25, v26, v27, automap_typeg, 144); |
||||
DrawLine(v25, v5, v4, automap_typeg, 144); |
||||
DrawLine(v25, v5, v27, automap_typeg, 144); |
||||
} |
||||
else |
||||
{ |
||||
v29 = v5; |
||||
v28 = v4 + AutoMapXPos; |
||||
v9 = AutoMapYPos + v5; |
||||
LABEL_36: |
||||
DrawLine(v4, v9, v28, v29, 200); |
||||
} |
||||
} |
||||
break; |
||||
default: |
||||
return; |
||||
} |
||||
} |
||||
// 4B84BC: using guessed type int AutoMapXPos;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B84C8: using guessed type int AMPlayerY;
|
||||
|
||||
void __cdecl DrawAutomapPlr() |
||||
{ |
||||
int v0; // ebx
|
||||
int v1; // eax
|
||||
int v2; // ecx
|
||||
int v3; // esi
|
||||
int v4; // edi
|
||||
int v5; // edx
|
||||
int v6; // ecx
|
||||
int v7; // eax
|
||||
int v8; // ecx
|
||||
int v9; // [esp-Ch] [ebp-20h]
|
||||
int v10; // [esp-8h] [ebp-1Ch]
|
||||
int v11; // [esp+Ch] [ebp-8h]
|
||||
int v12; // [esp+10h] [ebp-4h]
|
||||
|
||||
v0 = myplr; |
||||
if ( plr[myplr]._pmode == PM_WALK3 ) |
||||
{ |
||||
v1 = plr[v0]._px; |
||||
v2 = plr[v0]._py; |
||||
if ( plr[v0]._pdir == 2 ) |
||||
++v1; |
||||
else |
||||
++v2; |
||||
} |
||||
else |
||||
{ |
||||
v1 = plr[v0].WorldX; |
||||
v2 = plr[v0].WorldY; |
||||
} |
||||
v11 = v1 - 2 * AutoMapXOfs - ViewX; |
||||
v12 = v2 - 2 * AutoMapYOfs - ViewY; |
||||
v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pxoff / 100 >> 1) |
||||
+ AutoMapYPos * (v11 - v12) |
||||
+ 384; |
||||
if ( invflag || sbookflag ) |
||||
v3 = (AutoMapScale * ScrollInfo._sxoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pxoff / 100 >> 1) |
||||
+ AutoMapYPos * (v11 - v12) |
||||
+ 224; |
||||
if ( chrflag || questlog ) |
||||
v3 += 160; |
||||
v4 = AMPlayerX * (v12 + v11) |
||||
+ (AutoMapScale * ScrollInfo._syoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pyoff / 100 >> 1) |
||||
+ 336 |
||||
- AMPlayerX; |
||||
switch ( plr[v0]._pdir ) |
||||
{ |
||||
case DIR_S: |
||||
DrawLine(v3, v4, v3, v4 + AutoMapYPos, 153); |
||||
DrawLine(v3, AutoMapYPos + v4, v3 + AMPlayerY, v4 + AMPlayerX, 153); |
||||
v10 = v4 + AMPlayerX; |
||||
v9 = v3 - AMPlayerY; |
||||
v5 = AutoMapYPos + v4; |
||||
goto LABEL_19; |
||||
case DIR_SW: |
||||
DrawLine( |
||||
v3, |
||||
AMPlayerX * (v12 + v11) |
||||
+ (AutoMapScale * ScrollInfo._syoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pyoff / 100 >> 1) |
||||
+ 336 |
||||
- AMPlayerX, |
||||
v3 - AutoMapYPos, |
||||
AMPlayerX * (v12 + v11) |
||||
+ (AutoMapScale * ScrollInfo._syoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pyoff / 100 >> 1) |
||||
+ 336, |
||||
153); |
||||
DrawLine(v3 - AutoMapYPos, AMPlayerX + v4, v3 - AMPlayerY - AMPlayerX, v4, 153); |
||||
v7 = AMPlayerX; |
||||
v8 = v3; |
||||
v5 = AMPlayerX + v4; |
||||
v10 = AMPlayerX + v4; |
||||
goto LABEL_23; |
||||
case DIR_W: |
||||
DrawLine(v3, v4, v3 - AutoMapYPos, v4, 153); |
||||
DrawLine(v3 - AutoMapYPos, v4, v3 - AMPlayerX, v4 - AMPlayerY, 153); |
||||
v5 = v4; |
||||
v10 = v4 + AMPlayerY; |
||||
v9 = v3 - AMPlayerX; |
||||
goto LABEL_24; |
||||
case DIR_NW: |
||||
DrawLine(v3, v4, v3 - AutoMapYPos, v4 - AMPlayerX, 153); |
||||
DrawLine(v3 - AutoMapYPos, v4 - AMPlayerX, v3 - AMPlayerX, v4 - AMPlayerX, 153); |
||||
v7 = AMPlayerX; |
||||
v8 = v3 - AMPlayerY; |
||||
v10 = v4; |
||||
v5 = v4 - AMPlayerX; |
||||
LABEL_23: |
||||
v9 = v8 - v7; |
||||
LABEL_24: |
||||
v6 = v3 - AutoMapYPos; |
||||
goto LABEL_25; |
||||
case DIR_N: |
||||
DrawLine(v3, v4, v3, v4 - AutoMapYPos, 153); |
||||
DrawLine(v3, v4 - AutoMapYPos, v3 - AMPlayerY, v4 - AMPlayerX, 153); |
||||
v10 = v4 - AMPlayerX; |
||||
v5 = v4 - AutoMapYPos; |
||||
v9 = v3 + AMPlayerY; |
||||
LABEL_19: |
||||
v6 = v3; |
||||
goto LABEL_25; |
||||
case DIR_NE: |
||||
DrawLine(v3, v4, v3 + AutoMapYPos, v4 - AMPlayerX, 153); |
||||
DrawLine(AutoMapYPos + v3, v4 - AMPlayerX, v3 + AMPlayerX, v4 - AMPlayerX, 153); |
||||
v10 = v4; |
||||
v9 = v3 + AMPlayerX + AMPlayerY; |
||||
v5 = v4 - AMPlayerX; |
||||
goto LABEL_17; |
||||
case DIR_E: |
||||
DrawLine(v3, v4, v3 + AutoMapYPos, v4, 153); |
||||
DrawLine(AutoMapYPos + v3, v4, v3 + AMPlayerX, v4 - AMPlayerY, 153); |
||||
DrawLine(AutoMapYPos + v3, v4, v3 + AMPlayerX, v4 + AMPlayerY, 153); |
||||
break; |
||||
case DIR_SE: |
||||
DrawLine( |
||||
v3, |
||||
AMPlayerX * (v12 + v11) |
||||
+ (AutoMapScale * ScrollInfo._syoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pyoff / 100 >> 1) |
||||
+ 336 |
||||
- AMPlayerX, |
||||
v3 + AutoMapYPos, |
||||
AMPlayerX * (v12 + v11) |
||||
+ (AutoMapScale * ScrollInfo._syoff / 100 >> 1) |
||||
+ (AutoMapScale * plr[v0]._pyoff / 100 >> 1) |
||||
+ 336, |
||||
153); |
||||
DrawLine(AutoMapYPos + v3, AMPlayerX + v4, v3 + AMPlayerX + AMPlayerY, v4, 153); |
||||
v5 = AMPlayerX + v4; |
||||
v10 = AMPlayerX + v4; |
||||
v9 = v3 + AMPlayerX; |
||||
LABEL_17: |
||||
v6 = AutoMapYPos + v3; |
||||
LABEL_25: |
||||
DrawLine(v6, v5, v9, v10, 153); |
||||
break; |
||||
default: |
||||
return; |
||||
} |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B84C8: using guessed type int AMPlayerY;
|
||||
// 4B8968: using guessed type int sbookflag;
|
||||
// 69BD04: using guessed type int questlog;
|
||||
|
||||
short __fastcall GetAutomapType(int x, int y, BOOL view) |
||||
{ |
||||
int v3; // edi
|
||||
int v4; // esi
|
||||
int v6; // eax
|
||||
short v7; // bp
|
||||
|
||||
v3 = y; |
||||
v4 = x; |
||||
if ( view ) |
||||
{ |
||||
if ( x == -1 && y >= 0 && y < 40 && automapview[0][y] ) |
||||
{ |
||||
x = 0; |
||||
return ~GetAutomapType(x, y, 0) & 0x4000; |
||||
} |
||||
if ( y == -1 ) |
||||
{ |
||||
if ( x < 0 ) |
||||
return 0; |
||||
if ( x < 40 && automapview[x][0] ) |
||||
{ |
||||
y = 0; |
||||
return ~GetAutomapType(x, y, 0) & 0x4000; |
||||
} |
||||
} |
||||
} |
||||
if ( x < 0 ) |
||||
return 0; |
||||
if ( x >= 40 ) |
||||
return 0; |
||||
if ( y < 0 ) |
||||
return 0; |
||||
if ( y >= 40 ) |
||||
return 0; |
||||
v6 = y + 40 * x; |
||||
if ( !automapview[0][v6] && view ) |
||||
return 0; |
||||
v7 = automaptype[(unsigned char)dungeon[0][v6]]; |
||||
if ( v7 == 7 && ((unsigned short)GetAutomapType(x - 1, y, 0) >> 8) & 8 ) |
||||
{ |
||||
if ( ((unsigned short)GetAutomapType(v4, v3 - 1, 0) >> 8) & 4 ) |
||||
v7 = 1; |
||||
} |
||||
return v7; |
||||
} |
||||
|
||||
void __cdecl DrawAutomapGame() |
||||
{ |
||||
int v0; // esi
|
||||
char *v1; // eax
|
||||
char *v2; // eax
|
||||
char v3[256]; // [esp+4h] [ebp-100h]
|
||||
|
||||
v0 = 20; |
||||
if ( (unsigned char)gbMaxPlayers > 1u ) |
||||
{ |
||||
v1 = strcpy(v3, "game: "); |
||||
strcat(v1, szPlayerName); |
||||
PrintGameStr(8, 20, v3, 3); |
||||
v0 = 35; |
||||
if ( szPlayerDescript[0] ) |
||||
{ |
||||
v2 = strcpy(v3, "password: "); |
||||
strcat(v2, szPlayerDescript); |
||||
PrintGameStr(8, 35, v3, 3); |
||||
v0 = 50; |
||||
} |
||||
} |
||||
if ( setlevel ) |
||||
{ |
||||
PrintGameStr(8, v0, quest_level_names[(unsigned char)setlvlnum], 3); |
||||
} |
||||
else if ( currlevel ) |
||||
{ |
||||
sprintf(v3, "Level: %i", currlevel); |
||||
PrintGameStr(8, v0, v3, 3); |
||||
} |
||||
} |
||||
// 5CCB10: using guessed type char setlvlnum;
|
||||
// 5CF31D: using guessed type char setlevel;
|
||||
// 679660: using guessed type char gbMaxPlayers;
|
||||
|
||||
void __fastcall SetAutomapView(int x, int y) |
||||
{ |
||||
int xx = (x - 16) >> 1; |
||||
int yy = (y - 16) >> 1; |
||||
|
||||
if ( xx < 0 || xx >= DMAXX || yy < 0 || yy >= DMAXY ) { |
||||
return; |
||||
} |
||||
|
||||
automapview[xx][yy] = 1; |
||||
|
||||
USHORT maptype = GetAutomapType(xx, yy, FALSE); |
||||
USHORT solid = maptype & 0x4000; |
||||
|
||||
switch ( maptype & 0xF ) { |
||||
case 2: |
||||
if ( solid ) { |
||||
if ( GetAutomapType(xx, yy + 1, FALSE) == 0x4007 ) |
||||
automapview[xx][yy + 1] = 1; |
||||
} |
||||
else if ( GetAutomapType(xx - 1, yy, FALSE) & 0x4000 ) |
||||
automapview[xx - 1][yy] = 1; |
||||
break; |
||||
case 3: |
||||
if ( solid ) { |
||||
if ( GetAutomapType(xx + 1, yy, FALSE) == 0x4007 ) |
||||
automapview[xx + 1][yy] = 1; |
||||
} |
||||
else if ( GetAutomapType(xx, yy - 1, FALSE) & 0x4000 ) |
||||
automapview[xx][yy - 1] = 1; |
||||
break; |
||||
case 4: |
||||
if ( solid ) { |
||||
if ( GetAutomapType(xx, yy + 1, FALSE) == 0x4007 ) |
||||
automapview[xx][yy + 1] = 1; |
||||
if ( GetAutomapType(xx + 1, yy, FALSE) == 0x4007 ) |
||||
automapview[xx + 1][yy] = 1; |
||||
} |
||||
else { |
||||
if ( GetAutomapType(xx - 1, yy, FALSE) & 0x4000 ) |
||||
automapview[xx - 1][yy] = 1; |
||||
if ( GetAutomapType(xx, yy - 1, FALSE) & 0x4000 ) |
||||
automapview[xx][yy - 1] = 1; |
||||
if ( GetAutomapType(xx - 1, yy - 1, FALSE) & 0x4000 ) |
||||
automapview[xx - 1][yy - 1] = 1; |
||||
} |
||||
break; |
||||
case 5: |
||||
if ( solid ) { |
||||
if ( GetAutomapType(xx, yy - 1, FALSE) & 0x4000 ) |
||||
automapview[xx][yy - 1] = 1; |
||||
if ( GetAutomapType(xx, yy + 1, FALSE) == 0x4007 ) |
||||
automapview[xx][yy + 1] = 1; |
||||
} |
||||
else if ( GetAutomapType(xx - 1, yy, FALSE) & 0x4000 ) |
||||
automapview[xx - 1][yy] = 1; |
||||
break; |
||||
case 6: |
||||
if ( solid ) { |
||||
if ( GetAutomapType(xx - 1, yy, FALSE) & 0x4000 ) |
||||
automapview[xx - 1][yy] = 1; |
||||
if ( GetAutomapType(xx + 1, yy, FALSE) == 0x4007 ) |
||||
automapview[xx + 1][yy] = 1; |
||||
} |
||||
else if ( GetAutomapType(xx, yy - 1, FALSE) & 0x4000 ) |
||||
automapview[xx][yy - 1] = 1; |
||||
} |
||||
} |
||||
|
||||
void __cdecl AutomapZoomReset() |
||||
{ |
||||
AutoMapXOfs = 0; |
||||
AutoMapYOfs = 0; |
||||
AutoMapPosBits = (AutoMapScale << 6) / 100; |
||||
AutoMapXPos = AutoMapPosBits >> 1; |
||||
AutoMapYPos = AutoMapPosBits >> 2; |
||||
AMPlayerX = AutoMapPosBits >> 3; |
||||
AMPlayerY = AutoMapPosBits >> 4; |
||||
} |
||||
// 4B84B0: using guessed type int AutoMapXOfs;
|
||||
// 4B84B4: using guessed type int AutoMapYOfs;
|
||||
// 4B84B8: using guessed type int AutoMapPosBits;
|
||||
// 4B84BC: using guessed type int AutoMapXPos;
|
||||
// 4B84C0: using guessed type int AutoMapYPos;
|
||||
// 4B84C4: using guessed type int AMPlayerX;
|
||||
// 4B84C8: using guessed type int AMPlayerY;
|
||||
@ -0,0 +1,37 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __AUTOMAP_H__ |
||||
#define __AUTOMAP_H__ |
||||
|
||||
extern short automaptype[512]; |
||||
extern int AMdword_4B7E40; // weak
|
||||
extern int AMdword_4B7E44; // weak
|
||||
extern bool automapflag; // idb
|
||||
extern char AMbyte_4B7E4C[32]; |
||||
extern char automapview[DMAXX][DMAXY]; |
||||
extern int AutoMapScale; // idb
|
||||
extern int AutoMapXOfs; // weak
|
||||
extern int AutoMapYOfs; // weak
|
||||
extern int AutoMapPosBits; // weak
|
||||
extern int AutoMapXPos; // weak
|
||||
extern int AutoMapYPos; // weak
|
||||
extern int AMPlayerX; // weak
|
||||
extern int AMPlayerY; // weak
|
||||
|
||||
void __cdecl InitAutomapOnce(); |
||||
void __cdecl InitAutomap(); |
||||
void __cdecl StartAutomap(); |
||||
void __cdecl AutomapUp(); |
||||
void __cdecl AutomapDown(); |
||||
void __cdecl AutomapLeft(); |
||||
void __cdecl AutomapRight(); |
||||
void __cdecl AutomapZoomIn(); |
||||
void __cdecl AutomapZoomOut(); |
||||
void __cdecl DrawAutomap(); |
||||
void __fastcall DrawAutomapType(int screen_x, int screen_y, short automap_type); |
||||
void __cdecl DrawAutomapPlr(); |
||||
short __fastcall GetAutomapType(int x, int y, BOOL view); |
||||
void __cdecl DrawAutomapGame(); |
||||
void __fastcall SetAutomapView(int x, int y); |
||||
void __cdecl AutomapZoomReset(); |
||||
|
||||
#endif /* __AUTOMAP_H__ */ |
||||
@ -0,0 +1,173 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
void __cdecl CaptureScreen() |
||||
{ |
||||
PALETTEENTRY palette[256]; |
||||
char FileName[MAX_PATH]; |
||||
|
||||
HANDLE hObject = CaptureFile(FileName); |
||||
if ( hObject != INVALID_HANDLE_VALUE) |
||||
{ |
||||
DrawAndBlit(); |
||||
lpDDPalette->GetEntries(0, 0, 256, palette); |
||||
RedPalette(palette); |
||||
|
||||
lock_buf_priv(); |
||||
bool success = CaptureHdr(hObject, 640, 480); |
||||
if (success) |
||||
{ |
||||
success = CapturePix(hObject, 640, 480, 768, (BYTE*)gpBuffer->row[0].pixels); |
||||
if (success) |
||||
{ |
||||
success = CapturePal(hObject, palette); |
||||
} |
||||
} |
||||
unlock_buf_priv(); |
||||
CloseHandle(hObject); |
||||
|
||||
if (!success) |
||||
DeleteFile(FileName); |
||||
|
||||
Sleep(300); |
||||
lpDDPalette->SetEntries(0, 0, 256, palette); |
||||
} |
||||
} |
||||
|
||||
bool __fastcall CaptureHdr(HANDLE hFile, short width, short height) |
||||
{ |
||||
PCXHeader Buffer; |
||||
memset(&Buffer, 0, sizeof(Buffer)); |
||||
|
||||
Buffer.xmax = width - 1; |
||||
Buffer.vertRes = height; |
||||
Buffer.manufacturer = 10; |
||||
Buffer.version = 5; |
||||
Buffer.encoding = 1; |
||||
Buffer.bitsPerPixel = 8; |
||||
Buffer.ymax = height - 1; |
||||
Buffer.horzRes = width; |
||||
Buffer.numColorPlanes = 1; |
||||
Buffer.bytesPerScanLine = width; |
||||
|
||||
DWORD lpNumBytes; |
||||
return WriteFile(hFile, &Buffer, sizeof(Buffer), &lpNumBytes, NULL) && lpNumBytes == sizeof(Buffer); |
||||
} |
||||
|
||||
bool __fastcall CapturePal(HANDLE hFile, PALETTEENTRY *palette) |
||||
{ |
||||
char *v3; |
||||
char Buffer[769]; |
||||
|
||||
Buffer[0] = 12; |
||||
v3 = &Buffer[1]; |
||||
for (int i = 256; i != 0; --i) |
||||
{ |
||||
v3[0] = palette->peRed; |
||||
v3[1] = palette->peGreen; |
||||
v3[2] = palette->peBlue; |
||||
|
||||
palette++; |
||||
v3 += 3; |
||||
} |
||||
|
||||
DWORD lpNumBytes; |
||||
return WriteFile(hFile, Buffer, sizeof(Buffer), &lpNumBytes, NULL) && lpNumBytes == sizeof(Buffer); |
||||
} |
||||
|
||||
bool __fastcall CapturePix(HANDLE hFile, WORD width, WORD height, WORD stride, BYTE *pixels) |
||||
{ |
||||
int writeSize; |
||||
DWORD lpNumBytes; |
||||
|
||||
BYTE *pBuffer = (BYTE *)DiabloAllocPtr(2 * width); |
||||
do |
||||
{ |
||||
if ( !height ) |
||||
{ |
||||
mem_free_dbg(pBuffer); |
||||
return 1; |
||||
} |
||||
height--; |
||||
BYTE *pBufferEnd = CaptureEnc(pixels, pBuffer, width); |
||||
pixels += stride; |
||||
writeSize = pBufferEnd - pBuffer; |
||||
} |
||||
while (WriteFile(hFile, pBuffer, writeSize, &lpNumBytes, 0) && lpNumBytes == writeSize); |
||||
return 0; |
||||
} |
||||
|
||||
BYTE *__fastcall CaptureEnc(BYTE *src, BYTE *dst, int width) |
||||
{ |
||||
do |
||||
{ |
||||
BYTE rlePixel = *src++; |
||||
--width; |
||||
|
||||
int rleLength = 1; |
||||
while (rlePixel == *src) |
||||
{ |
||||
if (rleLength >= 63) |
||||
break; |
||||
if (!width) |
||||
break; |
||||
++rleLength; |
||||
|
||||
--width; |
||||
++src; |
||||
} |
||||
|
||||
if (rlePixel > 0xBF || rleLength > 1) |
||||
{ |
||||
*dst++ = rleLength | 0xC0; |
||||
} |
||||
*dst++ = rlePixel; |
||||
} while (width); |
||||
return dst; |
||||
} |
||||
|
||||
HANDLE __fastcall CaptureFile(char *dst_path) |
||||
{ |
||||
bool num_used[100] = { false }; |
||||
|
||||
_finddata_t finder; |
||||
int hFind = _findfirst("screen??.PCX", &finder); |
||||
if (hFind != -1) |
||||
{ |
||||
do |
||||
{ |
||||
if (isdigit(finder.name[6]) && isdigit(finder.name[7])) |
||||
{ |
||||
num_used[10 * (finder.name[6] - '0') + (finder.name[7] - '0')] = true; |
||||
} |
||||
} |
||||
while (_findnext(hFind, &finder) == 0); |
||||
} |
||||
|
||||
int free_num = 0; |
||||
while (num_used[free_num]) |
||||
{ |
||||
++free_num; |
||||
if (free_num >= 100) |
||||
return INVALID_HANDLE_VALUE; |
||||
} |
||||
|
||||
sprintf(dst_path, "screen%02d.PCX", free_num); |
||||
return CreateFile(dst_path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
||||
} |
||||
|
||||
void __fastcall RedPalette(PALETTEENTRY *pal) |
||||
{ |
||||
PALETTEENTRY red[256]; |
||||
|
||||
for(int i = 0; i < 256; i++) |
||||
{ |
||||
red[i].peRed = pal[i].peRed; |
||||
red[i].peGreen = 0; |
||||
red[i].peBlue = 0; |
||||
red[i].peFlags = 0; |
||||
} |
||||
|
||||
lpDDPalette->SetEntries(0, 0, 256, red); |
||||
} |
||||
@ -0,0 +1,13 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __CAPTURE_H__ |
||||
#define __CAPTURE_H__ |
||||
|
||||
void __cdecl CaptureScreen(); |
||||
bool __fastcall CaptureHdr(HANDLE hFile, short width, short height); |
||||
bool __fastcall CapturePal(HANDLE hFile, PALETTEENTRY *palette); |
||||
bool __fastcall CapturePix(HANDLE hFile, WORD width, WORD height, WORD stride, BYTE *pixels); |
||||
BYTE *__fastcall CaptureEnc(BYTE *src, BYTE *dst, int width); |
||||
HANDLE __fastcall CaptureFile(char *dst_path); |
||||
void __fastcall RedPalette(PALETTEENTRY *pal); |
||||
|
||||
#endif /* __CAPTURE_H__ */ |
||||
@ -0,0 +1,191 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifdef MINIWIN |
||||
#define srand srand_miniwin |
||||
#define rand rand_miniwin |
||||
#endif |
||||
|
||||
int __fastcall codec_decode(void *pbSrcDst, int size, char *pszPassword) |
||||
{ |
||||
unsigned int v3; // ebx
|
||||
char *v4; // esi
|
||||
int v5; // ebx
|
||||
signed int v7; // ecx
|
||||
int v8; // esi
|
||||
char v9[128]; // [esp+8h] [ebp-98h]
|
||||
char dst[20]; // [esp+88h] [ebp-18h]
|
||||
int v11; // [esp+9Ch] [ebp-4h]
|
||||
char *passworda; // [esp+A8h] [ebp+8h]
|
||||
|
||||
v3 = size; |
||||
v4 = (char *)pbSrcDst; |
||||
codec_init_key(0, pszPassword); |
||||
if ( v3 <= 8 ) |
||||
return 0; |
||||
v5 = v3 - 8; |
||||
v11 = v5; |
||||
if ( v5 & 0x3F ) |
||||
return 0; |
||||
passworda = (char *)v5; |
||||
if ( v5 ) |
||||
{ |
||||
do |
||||
{ |
||||
memcpy(v9, v4, 0x40u); |
||||
SHA1Result(0, dst); |
||||
v7 = 0; |
||||
do |
||||
{ |
||||
v9[v7] ^= dst[v7 % 20]; |
||||
++v7; |
||||
} |
||||
while ( v7 < 64 ); |
||||
SHA1Calculate(0, v9, 0); |
||||
memset(dst, 0, 0x14u); |
||||
memcpy(v4, v9, 0x40u); |
||||
v4 += 64; |
||||
passworda -= 64; |
||||
} |
||||
while ( passworda ); |
||||
v5 = v11; |
||||
} |
||||
memset(v9, 0, 0x80u); |
||||
if ( !v4[4] ) |
||||
{ |
||||
SHA1Result(0, dst); |
||||
if ( *(_DWORD *)v4 == *(_DWORD *)dst ) |
||||
{ |
||||
v8 = v5 + (unsigned char)v4[5] - 64; |
||||
goto LABEL_14; |
||||
} |
||||
memset(dst, 0, 0x14u); |
||||
} |
||||
v8 = 0; |
||||
LABEL_14: |
||||
SHA1Clear(); |
||||
return v8; |
||||
} |
||||
// 4034D9: using guessed type char var_98[128];
|
||||
|
||||
void __fastcall codec_init_key(int unused, char *pszPassword) |
||||
{ |
||||
char *v2; // edi
|
||||
char *v3; // esi
|
||||
int v4; // eax
|
||||
signed int v5; // ecx
|
||||
char v6; // dl
|
||||
unsigned int v7; // ecx
|
||||
signed int v8; // esi
|
||||
char v9[136]; // [esp+Ch] [ebp-E0h]
|
||||
char v10[64]; // [esp+94h] [ebp-58h]
|
||||
char dst[20]; // [esp+D4h] [ebp-18h]
|
||||
int v12; // [esp+E8h] [ebp-4h]
|
||||
|
||||
v2 = pszPassword; |
||||
srand(0x7058u); |
||||
v3 = v9; |
||||
v12 = 136; |
||||
do |
||||
{ |
||||
*v3++ = rand(); |
||||
--v12; |
||||
} |
||||
while ( v12 ); |
||||
v4 = 0; |
||||
v5 = 0; |
||||
do |
||||
{ |
||||
if ( !v2[v4] ) |
||||
v4 = 0; |
||||
v6 = v2[v4++]; |
||||
v10[v5++] = v6; |
||||
} |
||||
while ( v5 < 64 ); |
||||
SHA1Reset(0); |
||||
SHA1Calculate(0, v10, dst); |
||||
SHA1Clear(); |
||||
v7 = 0; |
||||
do |
||||
{ |
||||
v9[v7] ^= dst[(signed int)v7 % 20]; |
||||
++v7; |
||||
} |
||||
while ( v7 < 0x88 ); |
||||
memset(v10, 0, 0x40u); |
||||
memset(dst, 0, 0x14u); |
||||
v8 = 0; |
||||
do |
||||
{ |
||||
SHA1Reset(v8); |
||||
SHA1Calculate(v8++, &v9[72], 0); |
||||
} |
||||
while ( v8 < 3 ); |
||||
memset(v9, 0, 0x88u); |
||||
} |
||||
// 4035DB: using guessed type char var_E0[72];
|
||||
// 4035DB: using guessed type char var_58[64];
|
||||
// 4035DB: using guessed type char dst[20];
|
||||
|
||||
int __fastcall codec_get_encoded_len(int dwSrcBytes) |
||||
{ |
||||
if ( dwSrcBytes & 0x3F ) |
||||
dwSrcBytes += 64 - (dwSrcBytes & 0x3F); |
||||
return dwSrcBytes + 8; |
||||
} |
||||
|
||||
void __fastcall codec_encode(void *pbSrcDst, int size, int size_64, char *pszPassword) |
||||
{ |
||||
char *v4; // esi
|
||||
char v5; // bl
|
||||
size_t v6; // edi
|
||||
signed int v7; // ecx
|
||||
char v9[128]; // [esp+8h] [ebp-ACh]
|
||||
char v10[20]; // [esp+88h] [ebp-2Ch]
|
||||
char dst[20]; // [esp+9Ch] [ebp-18h]
|
||||
size_t v12; // [esp+B0h] [ebp-4h]
|
||||
|
||||
v4 = (char *)pbSrcDst; |
||||
v12 = size; |
||||
if ( size_64 != codec_get_encoded_len(size) ) |
||||
TermMsg("Invalid encode parameters"); |
||||
codec_init_key(1, pszPassword); |
||||
v5 = 0; |
||||
if ( v12 ) |
||||
{ |
||||
do |
||||
{ |
||||
v6 = v12; |
||||
if ( v12 >= 0x40 ) |
||||
v6 = 64; |
||||
memcpy(v9, v4, v6); |
||||
if ( v6 < 0x40 ) |
||||
memset(&v9[v6], 0, 64 - v6); |
||||
SHA1Result(0, dst); |
||||
SHA1Calculate(0, v9, 0); |
||||
v7 = 0; |
||||
do |
||||
{ |
||||
v9[v7] ^= dst[v7 % 20]; |
||||
++v7; |
||||
} |
||||
while ( v7 < 64 ); |
||||
memset(dst, 0, 0x14u); |
||||
memcpy(v4, v9, 0x40u); |
||||
v4 += 64; |
||||
v12 -= v6; |
||||
} |
||||
while ( v12 ); |
||||
v5 = v6; |
||||
} |
||||
memset(v9, 0, 0x80u); |
||||
SHA1Result(0, v10); |
||||
v4[4] = 0; |
||||
*((_WORD *)v4 + 3) = 0; |
||||
*(_DWORD *)v4 = *(_DWORD *)v10; |
||||
v4[5] = v5; |
||||
SHA1Clear(); |
||||
} |
||||
// 4036BE: using guessed type char var_AC[128];
|
||||
// 4036BE: using guessed type char dst[20];
|
||||
@ -0,0 +1,10 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __CODEC_H__ |
||||
#define __CODEC_H__ |
||||
|
||||
int __fastcall codec_decode(void *pbSrcDst, int size, char *pszPassword); |
||||
void __fastcall codec_init_key(int unused, char *pszPassword); |
||||
int __fastcall codec_get_encoded_len(int dwSrcBytes); |
||||
void __fastcall codec_encode(void *pbSrcDst, int size, int size_64, char *pszPassword); |
||||
|
||||
#endif /* __CODEC_H__ */ |
||||
@ -0,0 +1,141 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __CONTROL_H__ |
||||
#define __CONTROL_H__ |
||||
|
||||
extern char sgbNextTalkSave; // weak
|
||||
extern char sgbTalkSavePos; // weak
|
||||
extern void *pDurIcons; |
||||
extern void *pChrButtons; |
||||
extern int drawhpflag; // idb
|
||||
extern int dropGoldFlag; // weak
|
||||
extern int panbtn[8]; |
||||
extern int chrbtn[4]; |
||||
extern void *pMultiBtns; |
||||
extern void *pPanelButtons; |
||||
extern void *pChrPanel; |
||||
extern int lvlbtndown; // weak
|
||||
extern char sgszTalkSave[8][80]; |
||||
extern int dropGoldValue; // idb
|
||||
extern int drawmanaflag; // idb
|
||||
extern int chrbtnactive; // weak
|
||||
extern char sgszTalkMsg[80]; |
||||
extern void *pPanelText; |
||||
extern int frame_4B8800; // idb
|
||||
extern void *pLifeBuff; |
||||
extern void *pBtmBuff; |
||||
extern void *pTalkBtns; |
||||
extern int pstrjust[4]; |
||||
extern int pnumlines; // idb
|
||||
extern int pinfoflag; // weak
|
||||
extern int talkbtndown[3]; |
||||
extern int pSpell; // weak
|
||||
extern void *pManaBuff; |
||||
extern int infoclr; // weak
|
||||
extern int sgbPlrTalkTbl; // weak // should be char [4]
|
||||
extern void *pGBoxBuff; |
||||
extern void *pSBkBtnCel; |
||||
extern char tempstr[260]; |
||||
extern int sbooktab; // weak
|
||||
extern int pSplType; // weak
|
||||
extern int frame; // idb
|
||||
extern int initialDropGoldIndex; // idb
|
||||
extern int talkflag; // weak
|
||||
extern void *pSBkIconCels; |
||||
extern int sbookflag; // weak
|
||||
extern int chrflag; |
||||
extern int drawbtnflag; // idb
|
||||
extern void *pSpellBkCel; |
||||
extern char infostr[260]; |
||||
extern int numpanbtns; // weak
|
||||
extern void *pStatusPanel; |
||||
extern char panelstr[256]; |
||||
extern int panelflag; // weak
|
||||
extern char byte_4B8B88[256]; |
||||
extern int initialDropGoldValue; // idb
|
||||
extern void *pSpellCels; |
||||
extern int panbtndown; // weak
|
||||
extern void *pTalkPanel; // idb
|
||||
extern int spselflag; // weak
|
||||
|
||||
void __fastcall DrawSpellCel(int xp, int yp, char *Trans, int nCel, int w); |
||||
void __fastcall SetSpellTrans(char t); |
||||
void __cdecl DrawSpell(); |
||||
void __cdecl DrawSpellList(); |
||||
void __cdecl SetSpell(); |
||||
void __fastcall SetSpeedSpell(int slot); |
||||
void __fastcall ToggleSpell(int slot); |
||||
void __fastcall CPrintString(int No, unsigned char pszStr, int Just); /* check arg names */ |
||||
void __fastcall AddPanelString(char *str, int just); |
||||
void __cdecl ClearPanel(); |
||||
void __fastcall DrawPanelBox(int x, int y, int w, int h, int sx, int sy); |
||||
void __cdecl InitPanelStr(); |
||||
void __fastcall SetFlaskHeight(char *buf, int min, int max, int c, int r); |
||||
void __fastcall DrawFlask(void *a1, int a2, int a3, void *a4, int a5, int a6); |
||||
void __cdecl DrawLifeFlask(); |
||||
void __cdecl UpdateLifeFlask(); |
||||
void __cdecl DrawManaFlask(); |
||||
void __cdecl control_update_life_mana(); |
||||
void __cdecl UpdateManaFlask(); |
||||
void __cdecl InitControlPan(); |
||||
void __cdecl ClearCtrlPan(); |
||||
void __cdecl DrawCtrlPan(); |
||||
void __cdecl DoSpeedBook(); |
||||
void __cdecl DoPanBtn(); |
||||
void __fastcall control_set_button_down(int btn_id); |
||||
void __cdecl control_check_btn_press(); |
||||
void __cdecl DoAutoMap(); |
||||
void __cdecl CheckPanelInfo(); |
||||
void __cdecl CheckBtnUp(); |
||||
void __cdecl FreeControlPan(); |
||||
int __fastcall control_WriteStringToBuffer(char *str); |
||||
void __cdecl DrawInfoBox(); |
||||
void __fastcall control_print_info_str(int y, char *str, bool center, int lines); |
||||
void __fastcall PrintGameStr(int x, int y, char *str, int color); |
||||
void __cdecl DrawChr(); |
||||
void __fastcall ADD_PlrStringXY(int x, int y, int width, char *pszStr, char col); |
||||
void __fastcall MY_PlrStringXY(int x, int y, int width, char *pszStr, char col, int base); |
||||
void __cdecl CheckLvlBtn(); |
||||
void __cdecl ReleaseLvlBtn(); |
||||
void __cdecl DrawLevelUpIcon(); |
||||
void __cdecl CheckChrBtns(); |
||||
void __cdecl ReleaseChrBtns(); |
||||
void __cdecl DrawDurIcon(); |
||||
int __fastcall DrawDurIcon4Item(ItemStruct *pItem, int x, int c); |
||||
void __cdecl RedBack(); |
||||
int __fastcall GetSBookTrans(int ii, unsigned char townok); |
||||
void __cdecl DrawSpellBook(); |
||||
void __fastcall PrintSBookStr(int x, int y, bool cjustflag, char *pszStr, int bright); |
||||
void __cdecl CheckSBook(); |
||||
char *__fastcall get_pieces_str(int nGold); |
||||
void __fastcall DrawGoldSplit(int amount); |
||||
void __fastcall control_drop_gold(int vkey); |
||||
void __fastcall control_remove_gold(int pnum, int gold_index); |
||||
void __fastcall control_set_gold_curs(int pnum); |
||||
void __cdecl DrawTalkPan(); |
||||
char *__fastcall control_print_talk_msg(char *msg, int x, int y, int *a4, int just); |
||||
int __cdecl control_check_talk_btn(); |
||||
void __cdecl control_release_talk_btn(); |
||||
void __cdecl control_reset_talk_msg(); |
||||
void __cdecl control_type_message(); |
||||
void __cdecl control_reset_talk(); |
||||
int __fastcall control_talk_last_key(int a1); |
||||
int __fastcall control_presskeys(int a1); |
||||
void __cdecl control_press_enter(); |
||||
void __fastcall control_up_down(char a1); |
||||
|
||||
/* rdata */ |
||||
extern const unsigned char fontframe[127]; |
||||
extern const unsigned char fontkern[68]; |
||||
extern const int lineoffset[25]; |
||||
extern const unsigned char fontidx[256]; |
||||
|
||||
/* data */ |
||||
|
||||
extern unsigned char SpellITbl[37]; |
||||
extern int PanBtnPos[8][5]; |
||||
extern char *PanBtnHotKey[8]; |
||||
extern char *PanBtnStr[8]; |
||||
extern int attribute_inc_rects[4][4]; |
||||
extern int SpellPages[6][7]; |
||||
|
||||
#endif /* __CONTROL_H__ */ |
||||
@ -0,0 +1,36 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __CURSOR_H__ |
||||
#define __CURSOR_H__ |
||||
|
||||
extern int cursH; // weak
|
||||
extern int icursH28; // idb
|
||||
extern int cursW; // idb
|
||||
extern int pcursmonst; // idb
|
||||
extern int icursW28; // idb
|
||||
extern void *pCursCels; |
||||
extern int icursH; // weak
|
||||
extern char pcursinvitem; // weak
|
||||
extern int icursW; // weak
|
||||
extern char pcursitem; // weak
|
||||
extern char pcursobj; // weak
|
||||
extern char pcursplr; // weak
|
||||
extern int cursmx; |
||||
extern int cursmy; |
||||
extern int dword_4B8CCC; // weak
|
||||
extern int pcurs; // idb
|
||||
|
||||
void __cdecl InitCursor(); |
||||
void __cdecl FreeCursor(); |
||||
void __fastcall SetICursor(int i); |
||||
void __fastcall SetCursor(int i); |
||||
void __fastcall NewCursor(int i); |
||||
void __cdecl InitLevelCursor(); |
||||
void __cdecl CheckTown(); |
||||
void __cdecl CheckRportal(); |
||||
void __cdecl CheckCursMove(); |
||||
|
||||
/* rdata */ |
||||
extern const int InvItemWidth[180]; |
||||
extern const int InvItemHeight[180]; |
||||
|
||||
#endif /* __CURSOR_H__ */ |
||||
@ -0,0 +1,151 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
int spurtndx; // weak
|
||||
DeadStruct dead[MAXDEAD]; |
||||
int stonendx; |
||||
#endif |
||||
|
||||
void __cdecl InitDead() |
||||
{ |
||||
int v0; // ebx
|
||||
int *v1; // edx
|
||||
int *v2; // eax
|
||||
int v3; // ecx
|
||||
int v4; // edx
|
||||
int v5; // eax
|
||||
int v6; // edx
|
||||
int v7; // esi
|
||||
int *v8; // eax
|
||||
int v9; // edx
|
||||
CMonster *v10; // ecx
|
||||
char *v11; // edi
|
||||
int *v12; // ebx
|
||||
int mtypes[MAXMONSTERS]; // [esp+Ch] [ebp-330h]
|
||||
int *v14; // [esp+32Ch] [ebp-10h]
|
||||
int *v15; // [esp+330h] [ebp-Ch]
|
||||
int v16; // [esp+334h] [ebp-8h]
|
||||
int v17; // [esp+338h] [ebp-4h]
|
||||
|
||||
memset(mtypes, 0, sizeof(mtypes)); |
||||
v0 = 0; |
||||
if ( nummtypes > 0 ) |
||||
{ |
||||
v1 = &dead[0]._deadFrame; |
||||
v2 = &Monsters[0].Anims[4].Rate; |
||||
v17 = nummtypes; |
||||
do |
||||
{ |
||||
v15 = &mtypes[*((unsigned char *)v2 - 216)]; |
||||
if ( !*v15 ) |
||||
{ |
||||
qmemcpy(v1 - 8, v2 - 8, 0x20u); |
||||
v3 = *v2; |
||||
*((_BYTE *)v1 + 12) = 0; |
||||
*v1 = v3; |
||||
v1[1] = v2[21]; |
||||
v1[2] = v2[22]; |
||||
*((_BYTE *)v2 + 101) = ++v0; |
||||
v1 += 12; |
||||
*v15 = v0; |
||||
} |
||||
v2 += 82; |
||||
--v17; |
||||
} |
||||
while ( v17 ); |
||||
} |
||||
v16 = 0; |
||||
v4 = v0; |
||||
memset32(&dead[v0], (unsigned int)misfiledata[16].mAnimData[0], 8u); |
||||
_LOBYTE(dead[v4]._deadtrans) = 0; |
||||
dead[v4]._deadFrame = 8; |
||||
v5 = (unsigned int)misfiledata[18].mAnimData[0]; |
||||
dead[v4]._deadWidth = 128; |
||||
dead[v4]._deadWidth2 = 32; |
||||
v6 = v0 + 1; |
||||
spurtndx = v0 + 1; |
||||
memset32(&dead[v6], v5, 8u); |
||||
_LOBYTE(dead[v6]._deadtrans) = 0; |
||||
stonendx = v0 + 2; |
||||
v7 = nummonsters; |
||||
dead[v6]._deadFrame = 12; |
||||
dead[v6]._deadWidth = 128; |
||||
dead[v6]._deadWidth2 = 32; |
||||
v17 = v0 + 2; |
||||
if ( v7 > 0 ) |
||||
{ |
||||
v8 = &dead[v0 + 2]._deadFrame; |
||||
do |
||||
{ |
||||
v9 = monstactive[v16]; |
||||
if ( monster[v9]._uniqtype ) |
||||
{ |
||||
v10 = monster[v9].MType; |
||||
v11 = (char *)(v8 - 8); |
||||
v15 = (int *)8; |
||||
v14 = (int *)v10->Anims[4].Frames; |
||||
do |
||||
{ |
||||
v12 = v14; |
||||
++v14; |
||||
*(_DWORD *)v11 = *v12; |
||||
v11 += 4; |
||||
v15 = (int *)((char *)v15 - 1); |
||||
} |
||||
while ( v15 ); |
||||
*v8 = v10->Anims[4].Rate; |
||||
v8[1] = v10->flags_1; |
||||
v8[2] = v10->flags_2; |
||||
*((_BYTE *)v8 + 12) = monster[v9]._uniqtrans + 4; |
||||
monster[v9]._udeadval = ++v17; |
||||
v8 += 12; |
||||
} |
||||
++v16; |
||||
} |
||||
while ( v16 < v7 ); |
||||
} |
||||
} |
||||
// 4B8CD8: using guessed type int spurtndx;
|
||||
|
||||
void __fastcall AddDead(int dx, int dy, char dv, int ddir) |
||||
{ |
||||
dDead[dx][dy] = (dv & 0x1F) + 32 * ddir; |
||||
} |
||||
|
||||
void __cdecl SetDead() |
||||
{ |
||||
int v0; // eax
|
||||
int v1; // esi
|
||||
int v2; // ebp
|
||||
char (*v3)[112]; // ebx
|
||||
int v4; // edi
|
||||
int i; // [esp+0h] [ebp-4h]
|
||||
|
||||
v0 = 0; |
||||
for ( i = 0; i < nummonsters; ++i ) |
||||
{ |
||||
v1 = monstactive[v0]; |
||||
if ( monster[v1]._uniqtype ) |
||||
{ |
||||
v2 = 0; |
||||
v3 = dDead; |
||||
do |
||||
{ |
||||
v4 = 0; |
||||
do |
||||
{ |
||||
if ( ((*v3)[v4] & 0x1F) == monster[v1]._udeadval ) |
||||
ChangeLightXY((unsigned char)monster[v1].mlid, v2, v4); |
||||
++v4; |
||||
} |
||||
while ( v4 < 112 ); |
||||
++v3; |
||||
++v2; |
||||
} |
||||
while ( (signed int)v3 < (signed int)&dDead[112][0] ); |
||||
} |
||||
v0 = i + 1; |
||||
} |
||||
} |
||||
@ -0,0 +1,13 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DEAD_H__ |
||||
#define __DEAD_H__ |
||||
|
||||
extern int spurtndx; // weak
|
||||
extern DeadStruct dead[MAXDEAD]; |
||||
extern int stonendx; |
||||
|
||||
void __cdecl InitDead(); |
||||
void __fastcall AddDead(int dx, int dy, char dv, int ddir); |
||||
void __cdecl SetDead(); |
||||
|
||||
#endif /* __DEAD_H__ */ |
||||
@ -0,0 +1,247 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
void *pSquareCel; |
||||
char dMonsDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; |
||||
char dFlagDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; |
||||
#endif |
||||
|
||||
void __cdecl LoadDebugGFX() |
||||
{ |
||||
if ( visiondebug ) |
||||
pSquareCel = LoadFileInMem("Data\\Square.CEL", 0); |
||||
} |
||||
// 525720: using guessed type int visiondebug;
|
||||
|
||||
void __cdecl FreeDebugGFX() |
||||
{ |
||||
void *v0; // ecx
|
||||
|
||||
v0 = pSquareCel; |
||||
pSquareCel = 0; |
||||
mem_free_dbg(v0); |
||||
} |
||||
|
||||
void __cdecl CheckDungeonClear() |
||||
{ |
||||
int i; |
||||
int j; |
||||
|
||||
for(i = 0; i < MAXDUNX; i++) |
||||
{ |
||||
for(j = 0; j < MAXDUNY; j++) |
||||
{ |
||||
if ( dMonster[i][j] ) |
||||
TermMsg("Monsters not cleared"); |
||||
if ( dPlayer[i][j] ) |
||||
TermMsg("Players not cleared"); |
||||
|
||||
dMonsDbg[currlevel][i][j] = dFlags[i][j] & 2; |
||||
dFlagDbg[currlevel][i][j] = dFlags[i][j] & 8; |
||||
} |
||||
} |
||||
} |
||||
|
||||
#ifdef _DEBUG |
||||
void __cdecl GiveGoldCheat() |
||||
{ |
||||
int i; // esi
|
||||
int ni; // ebp
|
||||
|
||||
for(i = 0; i < 40; i++) |
||||
{ |
||||
if ( !plr[myplr].InvGrid[i] ) |
||||
{ |
||||
ni = plr[myplr]._pNumInv++; |
||||
SetPlrHandItem(&plr[myplr].InvList[ni], IDI_GOLD); |
||||
GetPlrHandSeed(&plr[myplr].InvList[ni]); |
||||
plr[myplr].InvList[ni]._ivalue = 5000; |
||||
plr[myplr].InvList[ni]._iCurs = 6; |
||||
plr[myplr]._pGold += 5000; |
||||
plr[myplr].InvGrid[i] = plr[myplr]._pNumInv; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void __cdecl StoresCheat() |
||||
{ |
||||
int i; // eax
|
||||
|
||||
numpremium = 0; |
||||
|
||||
for(i = 0; i < 6; i++) |
||||
premiumitem[i]._itype = -1; |
||||
|
||||
SpawnPremium(30); |
||||
|
||||
for(i = 0; i < 20; i++) |
||||
witchitem[i]._itype = -1; |
||||
|
||||
SpawnWitch(30); |
||||
} |
||||
|
||||
void __cdecl TakeGoldCheat() |
||||
{ |
||||
int i; // esi
|
||||
char ig; // cl
|
||||
|
||||
for(i = 0; i < 40; i++) |
||||
{ |
||||
ig = plr[myplr].InvGrid[i]; |
||||
if ( ig > 0 && plr[myplr].InvList[ig - 1]._itype == ITYPE_GOLD ) |
||||
RemoveInvItem(myplr, ig - 1); |
||||
} |
||||
|
||||
for(i = 0; i < 8; i++) |
||||
{ |
||||
if ( plr[myplr].SpdList[i]._itype == ITYPE_GOLD ) |
||||
plr[myplr].SpdList[i]._itype = -1; |
||||
} |
||||
|
||||
plr[myplr]._pGold = 0; |
||||
} |
||||
|
||||
void __cdecl MaxSpellsCheat() |
||||
{ |
||||
int i; // ebp
|
||||
|
||||
for(i = 1; i < 37; i++) |
||||
{ |
||||
if ( spelldata[i].sBookLvl != -1 ) |
||||
{ |
||||
*(_QWORD *)plr[myplr]._pMemSpells |= (__int64)1 << (i - 1); |
||||
plr[myplr]._pSplLvl[i] = 10; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void __fastcall SetSpellLevelCheat(char spl, int spllvl) |
||||
{ |
||||
*(_QWORD *)plr[myplr]._pMemSpells |= (__int64)1 << (spl - 1); |
||||
plr[myplr]._pSplLvl[spl] = spllvl; |
||||
} |
||||
|
||||
void __cdecl SetAllSpellsCheat() |
||||
{ |
||||
SetSpellLevelCheat(SPL_FIREBOLT, 8); |
||||
SetSpellLevelCheat(SPL_CBOLT, 11); |
||||
SetSpellLevelCheat(SPL_HBOLT, 10); |
||||
SetSpellLevelCheat(SPL_HEAL, 7); |
||||
SetSpellLevelCheat(SPL_HEALOTHER, 5); |
||||
SetSpellLevelCheat(SPL_LIGHTNING, 9); |
||||
SetSpellLevelCheat(SPL_FIREWALL, 5); |
||||
SetSpellLevelCheat(SPL_TELEKINESIS, 3); |
||||
SetSpellLevelCheat(SPL_TOWN, 3); |
||||
SetSpellLevelCheat(SPL_FLASH, 3); |
||||
SetSpellLevelCheat(SPL_RNDTELEPORT, 2); |
||||
SetSpellLevelCheat(SPL_MANASHIELD, 2); |
||||
SetSpellLevelCheat(SPL_WAVE, 4); |
||||
SetSpellLevelCheat(SPL_FIREBALL, 3); |
||||
SetSpellLevelCheat(SPL_STONE, 1); |
||||
SetSpellLevelCheat(SPL_CHAIN, 1); |
||||
SetSpellLevelCheat(SPL_GUARDIAN, 4); |
||||
SetSpellLevelCheat(SPL_ELEMENT, 3); |
||||
SetSpellLevelCheat(SPL_NOVA, 1); |
||||
SetSpellLevelCheat(SPL_GOLEM, 2); |
||||
SetSpellLevelCheat(SPL_FLARE, 1); |
||||
SetSpellLevelCheat(SPL_BONESPIRIT, 1); |
||||
} |
||||
|
||||
void __fastcall PrintDebugPlayer(bool bNextPlayer) |
||||
{ |
||||
char dstr[128]; // [esp+Ch] [ebp-80h]
|
||||
|
||||
if ( bNextPlayer ) |
||||
dbgplr = ((_BYTE)dbgplr + 1) & 3; |
||||
|
||||
sprintf(dstr, "Plr %i : Active = %i", dbgplr, plr[dbgplr].plractive); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
|
||||
if ( plr[dbgplr].plractive ) |
||||
{ |
||||
sprintf(dstr, " Plr %i is %s", dbgplr, plr[dbgplr]._pName); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, " Lvl = %i : Change = %i", plr[dbgplr].plrlevel, plr[dbgplr]._pLvlChanging); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, " x = %i, y = %i : tx = %i, ty = %i", plr[dbgplr].WorldX, plr[dbgplr].WorldY, plr[dbgplr]._ptargx, plr[dbgplr]._ptargy); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, " mode = %i : daction = %i : walk[0] = %i", plr[dbgplr]._pmode, plr[dbgplr].destAction, plr[dbgplr].walkpath[0]); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, " inv = %i : hp = %i", plr[dbgplr]._pInvincible, plr[dbgplr]._pHitPoints); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
} |
||||
} |
||||
|
||||
void __cdecl PrintDebugQuest() |
||||
{ |
||||
char dstr[128]; // [esp+0h] [ebp-80h]
|
||||
|
||||
sprintf(dstr, "Quest %i : Active = %i, Var1 = %i", dbgqst, quests[dbgqst]._qactive, quests[dbgqst]._qvar1); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
if ( ++dbgqst == MAXQUESTS ) |
||||
dbgqst = 0; |
||||
} |
||||
|
||||
void __fastcall PrintDebugMonster(int m) |
||||
{ |
||||
bool bActive; // ecx
|
||||
int i; // eax
|
||||
char dstr[128]; // [esp+Ch] [ebp-80h]
|
||||
|
||||
sprintf(dstr, "Monster %i = %s", m, monster[m].mName); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, "X = %i, Y = %i", monster[m]._mx, monster[m]._my); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, "Enemy = %i, HP = %i", monster[m]._menemy, monster[m]._mhitpoints); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
sprintf(dstr, "Mode = %i, Var1 = %i", monster[m]._mmode, monster[m]._mVar1); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
|
||||
bActive = 0; |
||||
|
||||
for(i = 0; i < nummonsters; i++) |
||||
{ |
||||
if ( monstactive[i] == m ) |
||||
bActive = 1; |
||||
} |
||||
|
||||
sprintf(dstr, "Active List = %i, Squelch = %i", bActive, monster[m]._msquelch); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
} |
||||
|
||||
void __cdecl GetDebugMonster() |
||||
{ |
||||
int v0; // ecx
|
||||
int v1; // eax
|
||||
|
||||
v0 = pcursmonst; |
||||
if ( pcursmonst == -1 ) |
||||
{ |
||||
v1 = dMonster[cursmx][cursmy]; |
||||
if ( v1 ) |
||||
{ |
||||
v0 = v1 - 1; |
||||
if ( v1 <= 0 ) |
||||
v0 = -1 - v1; |
||||
} |
||||
else |
||||
{ |
||||
v0 = dbgmon; |
||||
} |
||||
} |
||||
PrintDebugMonster(v0); |
||||
} |
||||
|
||||
void __cdecl NextDebugMonster() |
||||
{ |
||||
char dstr[128]; // [esp+0h] [ebp-80h]
|
||||
|
||||
if ( dbgmon++ == MAXMONSTERS ) |
||||
dbgmon = 0; |
||||
|
||||
sprintf(dstr, "Current debug monster = %i", dbgmon); |
||||
NetSendCmdString(1 << myplr, dstr); |
||||
} |
||||
#endif |
||||
@ -0,0 +1,26 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DEBUG_H__ |
||||
#define __DEBUG_H__ |
||||
|
||||
extern void *pSquareCel; |
||||
extern char dMonsDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; |
||||
extern char dFlagDbg[NUMLEVELS][MAXDUNX][MAXDUNY]; |
||||
|
||||
void __cdecl LoadDebugGFX(); |
||||
void __cdecl FreeDebugGFX(); |
||||
void __cdecl CheckDungeonClear(); |
||||
#ifdef _DEBUG |
||||
void __cdecl GiveGoldCheat(); |
||||
void __cdecl StoresCheat(); |
||||
void __cdecl TakeGoldCheat(); |
||||
void __cdecl MaxSpellsCheat(); |
||||
void __fastcall SetSpellLevelCheat(char spl, int spllvl); |
||||
void __cdecl SetAllSpellsCheat(); |
||||
void __fastcall PrintDebugPlayer(bool bNextPlayer); |
||||
void __cdecl PrintDebugQuest(); |
||||
void __fastcall PrintDebugMonster(int m); |
||||
void __cdecl GetDebugMonster(); |
||||
void __cdecl NextDebugMonster(); |
||||
#endif |
||||
|
||||
#endif /* __DEBUG_H__ */ |
||||
@ -0,0 +1,102 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DIABLO_H__ |
||||
#define __DIABLO_H__ |
||||
|
||||
extern int diablo_cpp_init_value; // weak
|
||||
extern HWND ghMainWnd; |
||||
extern int glMid1Seed[NUMLEVELS]; |
||||
extern int glMid2Seed[NUMLEVELS]; |
||||
extern int gnLevelTypeTbl[NUMLEVELS]; |
||||
extern int MouseY; // idb
|
||||
extern int MouseX; // idb
|
||||
extern bool gbGameLoopStartup; // idb
|
||||
extern int glSeedTbl[NUMLEVELS]; |
||||
extern int gbRunGame; // weak
|
||||
extern int glMid3Seed[NUMLEVELS]; |
||||
extern int gbRunGameResult; // weak
|
||||
extern int zoomflag; // weak
|
||||
extern int gbProcessPlayers; // weak
|
||||
extern int glEndSeed[NUMLEVELS]; |
||||
extern int dword_5256E8; // weak
|
||||
extern HINSTANCE ghInst; // idb
|
||||
extern int DebugMonsters[10]; |
||||
extern char cineflag; // weak
|
||||
extern int drawpanflag; // weak
|
||||
extern int visiondebug; // weak
|
||||
extern int scrollflag; /* unused */ |
||||
extern int light4flag; // weak
|
||||
extern int leveldebug; // weak
|
||||
extern int monstdebug; // weak
|
||||
extern int trigdebug; /* unused */ |
||||
extern int setseed; // weak
|
||||
extern int debugmonsttypes; // weak
|
||||
extern int PauseMode; // weak
|
||||
extern int sgnTimeoutCurs; |
||||
extern char sgbMouseDown; // weak
|
||||
extern int color_cycle_timer; // weak
|
||||
|
||||
void __cdecl diablo_cpp_init(); |
||||
void __cdecl FreeGameMem(); |
||||
int __fastcall diablo_init_menu(int a1, int bSinglePlayer); |
||||
void __fastcall run_game_loop(int uMsg); |
||||
void __fastcall start_game(int uMsg); |
||||
void __cdecl free_game(); |
||||
bool __cdecl diablo_get_not_running(); |
||||
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd); |
||||
void __fastcall diablo_parse_flags(char *args); |
||||
void __cdecl diablo_init_screen(); |
||||
BOOL __fastcall diablo_find_window(LPCSTR lpClassName); |
||||
void __fastcall diablo_reload_process(HMODULE hModule); |
||||
int __cdecl PressEscKey(); |
||||
LRESULT __stdcall DisableInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
||||
LRESULT __stdcall GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); |
||||
bool __fastcall LeftMouseDown(int a1); |
||||
bool __cdecl TryIconCurs(); |
||||
void __cdecl LeftMouseUp(); |
||||
void __cdecl RightMouseDown(); |
||||
void __fastcall j_gmenu_on_mouse_move(LPARAM lParam); |
||||
bool __fastcall PressSysKey(int wParam); |
||||
void __fastcall diablo_hotkey_msg(int dwMsg); |
||||
void __fastcall ReleaseKey(int vkey); |
||||
void __fastcall PressKey(int vkey); |
||||
void __cdecl diablo_pause_game(); |
||||
void __fastcall PressChar(int vkey); |
||||
void __cdecl LoadLvlGFX(); |
||||
void __cdecl LoadAllGFX(); |
||||
void __fastcall CreateLevel(int lvldir); |
||||
void __fastcall LoadGameLevel(BOOL firstflag, int lvldir); |
||||
void __fastcall game_loop(bool bStartup); |
||||
void __cdecl game_logic(); |
||||
void __fastcall timeout_cursor(bool bTimeout); |
||||
void __cdecl diablo_color_cyc_logic(); |
||||
|
||||
/* data */ |
||||
|
||||
extern int diablo_inf; // weak
|
||||
|
||||
/* rdata */ |
||||
|
||||
extern int fullscreen; // weak
|
||||
#ifdef _DEBUG |
||||
extern int showintrodebug; |
||||
extern int questdebug; |
||||
extern int debug_mode_key_s; |
||||
extern int debug_mode_key_w; |
||||
extern int debug_mode_key_inverted_v; |
||||
extern int debug_mode_dollar_sign; |
||||
extern int debug_mode_key_d; |
||||
extern int debug_mode_key_i; |
||||
extern int dbgplr; |
||||
extern int dbgqst; |
||||
extern int dbgmon; |
||||
extern int arrowdebug; |
||||
extern int frameflag; |
||||
extern int frameend; |
||||
extern int framerate; |
||||
extern int framestart; |
||||
#endif |
||||
extern int FriendlyMode; // weak
|
||||
extern char *spszMsgTbl[4]; // weak
|
||||
extern char *spszMsgKeyTbl[4]; // weak
|
||||
|
||||
#endif /* __DIABLO_H__ */ |
||||
@ -0,0 +1,113 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
int doom_quest_time; // weak
|
||||
int doom_stars_drawn; // weak
|
||||
void *pDoomCel; |
||||
int doomflag; // weak
|
||||
int DoomQuestState; // idb
|
||||
#endif |
||||
|
||||
/*
|
||||
void __cdecl doom_reset_state() |
||||
{ |
||||
if ( DoomQuestState <= 0 ) { |
||||
DoomQuestState = 0; |
||||
} |
||||
} |
||||
|
||||
void __cdecl doom_play_movie() |
||||
{ |
||||
if ( DoomQuestState < 36001 ) { |
||||
DoomQuestState++; |
||||
if ( DoomQuestState == 36001 ) { |
||||
PlayInGameMovie("gendata\\doom.smk"); |
||||
DoomQuestState++; |
||||
} |
||||
} |
||||
} |
||||
*/ |
||||
|
||||
int __cdecl doom_get_frame_from_time() |
||||
{ |
||||
if ( DoomQuestState == 36001 ) { |
||||
return 31; |
||||
} |
||||
|
||||
return DoomQuestState / 1200; |
||||
} |
||||
|
||||
void __cdecl doom_alloc_cel() |
||||
{ |
||||
pDoomCel = DiabloAllocPtr(229376); |
||||
} |
||||
|
||||
void __cdecl doom_cleanup() |
||||
{ |
||||
void *ptr = pDoomCel; |
||||
pDoomCel = NULL; |
||||
mem_free_dbg(ptr); |
||||
} |
||||
|
||||
void __cdecl doom_load_graphics() |
||||
{ |
||||
if ( doom_quest_time == 31 ) |
||||
{ |
||||
strcpy(tempstr, "Items\\Map\\MapZDoom.CEL"); |
||||
} |
||||
else if ( doom_quest_time < 10 ) |
||||
{ |
||||
sprintf(tempstr, "Items\\Map\\MapZ000%i.CEL", doom_quest_time); |
||||
} |
||||
else |
||||
{ |
||||
sprintf(tempstr, "Items\\Map\\MapZ00%i.CEL", doom_quest_time); |
||||
} |
||||
LoadFileWithMem(tempstr, pDoomCel); |
||||
} |
||||
// 525750: using guessed type int doom_quest_time;
|
||||
|
||||
void __cdecl doom_init() |
||||
{ |
||||
doomflag = 1; |
||||
doom_alloc_cel(); |
||||
doom_quest_time = doom_get_frame_from_time() == 31 ? 31 : 0; |
||||
doom_load_graphics(); |
||||
} |
||||
// 525750: using guessed type int doom_quest_time;
|
||||
// 52575C: using guessed type int doomflag;
|
||||
|
||||
void __cdecl doom_close() |
||||
{ |
||||
if ( doomflag ) { |
||||
doomflag = 0; |
||||
doom_cleanup(); |
||||
} |
||||
} |
||||
// 52575C: using guessed type int doomflag;
|
||||
|
||||
void __cdecl doom_draw() |
||||
{ |
||||
if ( !doomflag ) { |
||||
return; |
||||
} |
||||
|
||||
if ( doom_quest_time != 31 ) { |
||||
doom_stars_drawn++; |
||||
if ( doom_stars_drawn >= 5 ) { |
||||
doom_stars_drawn = 0; |
||||
doom_quest_time++; |
||||
if ( doom_quest_time > doom_get_frame_from_time() ) { |
||||
doom_quest_time = 0; |
||||
} |
||||
doom_load_graphics(); |
||||
} |
||||
} |
||||
|
||||
CelDecodeOnly(64, 511, pDoomCel, 1, 640); |
||||
} |
||||
// 525750: using guessed type int doom_quest_time;
|
||||
// 525754: using guessed type int doom_stars_drawn;
|
||||
// 52575C: using guessed type int doomflag;
|
||||
@ -0,0 +1,23 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DOOM_H__ |
||||
#define __DOOM_H__ |
||||
|
||||
extern int doom_quest_time; // weak
|
||||
extern int doom_stars_drawn; // weak
|
||||
extern void *pDoomCel; |
||||
extern int doomflag; // weak
|
||||
extern int DoomQuestState; // idb
|
||||
|
||||
/*
|
||||
void __cdecl doom_reset_state(); |
||||
void __cdecl doom_play_movie(); |
||||
*/ |
||||
int __cdecl doom_get_frame_from_time(); |
||||
void __cdecl doom_alloc_cel(); |
||||
void __cdecl doom_cleanup(); |
||||
void __cdecl doom_load_graphics(); |
||||
void __cdecl doom_init(); |
||||
void __cdecl doom_close(); |
||||
void __cdecl doom_draw(); |
||||
|
||||
#endif /* __DOOM_H__ */ |
||||
@ -0,0 +1,68 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DRLG_L1_H__ |
||||
#define __DRLG_L1_H__ |
||||
|
||||
extern char L5dungeon[80][80]; |
||||
extern char mydflags[40][40]; |
||||
extern int setloadflag; // weak
|
||||
extern int HR1; |
||||
extern int HR2; |
||||
extern int HR3; |
||||
extern int VR1; |
||||
extern int VR2; |
||||
extern int VR3; |
||||
extern void *pSetPiece; // idb
|
||||
|
||||
void __cdecl DRLG_Init_Globals(); |
||||
void __fastcall LoadL1Dungeon(char *sFileName, int vx, int vy); |
||||
void __cdecl DRLG_L1Floor(); |
||||
void __cdecl DRLG_L1Pass3(); |
||||
void __cdecl DRLG_InitL1Vals(); |
||||
void __fastcall LoadPreL1Dungeon(char *sFileName, int vx, int vy); |
||||
void __fastcall CreateL5Dungeon(int rseed, int entry); |
||||
void __cdecl DRLG_LoadL1SP(); |
||||
void __cdecl DRLG_FreeL1SP(); |
||||
void __fastcall DRLG_L5(int entry); |
||||
void __fastcall DRLG_PlaceDoor(int x, int y); |
||||
void __cdecl DRLG_L1Shadows(); |
||||
int __fastcall DRLG_PlaceMiniSet(const unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, int noquad, int ldir); |
||||
void __cdecl InitL5Dungeon(); |
||||
void __cdecl L5ClearFlags(); |
||||
void __cdecl L5firstRoom(); |
||||
void __fastcall L5drawRoom(int x, int y, int w, int h); |
||||
void __fastcall L5roomGen(int x, int y, int w, int h, BOOL dir); |
||||
bool __fastcall L5checkRoom(int x, int y, int width, int height); |
||||
int __cdecl L5GetArea(); |
||||
void __cdecl L5makeDungeon(); |
||||
void __cdecl L5makeDmt(); |
||||
void __cdecl L5AddWall(); |
||||
int __fastcall L5HWallOk(int i, int j); |
||||
int __fastcall L5VWallOk(int i, int j); |
||||
void __fastcall L5HorizWall(int i, int j, char p, int dx); |
||||
void __fastcall L5VertWall(int i, int j, char p, int dy); |
||||
void __cdecl L5tileFix(); |
||||
void __cdecl DRLG_L5Subs(); |
||||
void __cdecl L5FillChambers(); |
||||
void __fastcall DRLG_L5GChamber(int sx, int sy, bool topflag, bool bottomflag, bool leftflag, bool rightflag); |
||||
void __fastcall DRLG_L5GHall(int x1, int y1, int x2, int y2); |
||||
void __fastcall DRLG_L5SetRoom(int rx1, int ry1); |
||||
void __cdecl DRLG_L5FloodTVal(); |
||||
void __fastcall DRLG_L5FTVR(int i, int j, int x, int y, int d); |
||||
void __cdecl DRLG_L5TransFix(); |
||||
void __cdecl DRLG_L5DirtFix(); |
||||
void __cdecl DRLG_L5CornerFix(); |
||||
|
||||
/* rdata */ |
||||
extern const ShadowStruct SPATS[37]; |
||||
extern const unsigned char BSTYPES[206]; |
||||
extern const unsigned char L5BTYPES[206]; |
||||
extern const unsigned char STAIRSUP[]; |
||||
extern const unsigned char L5STAIRSUP[]; |
||||
extern const unsigned char STAIRSDOWN[]; |
||||
extern const unsigned char LAMPS[]; |
||||
extern const unsigned char PWATERIN[]; |
||||
|
||||
/* data */ |
||||
extern unsigned char L5ConvTbl[16]; |
||||
|
||||
#endif /* __DRLG_L1_H__ */ |
||||
@ -0,0 +1,173 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DRLG_L2_H__ |
||||
#define __DRLG_L2_H__ |
||||
|
||||
extern int nSx1; |
||||
extern int nSx2; // weak
|
||||
extern int nSy1; |
||||
extern int nSy2; // weak
|
||||
extern int nRoomCnt; |
||||
extern char predungeon[40][40]; |
||||
extern ROOMNODE RoomList[81]; |
||||
extern HALLNODE *pHallList; |
||||
|
||||
void __cdecl InitDungeon(); |
||||
void __cdecl L2LockoutFix(); |
||||
void __cdecl L2DoorFix(); |
||||
void __fastcall LoadL2Dungeon(char *sFileName, int vx, int vy); |
||||
void __cdecl DRLG_L2Pass3(); |
||||
void __fastcall LoadPreL2Dungeon(char *sFileName, int vx, int vy); |
||||
void __fastcall CreateL2Dungeon(int rseed, int entry); |
||||
void __cdecl DRLG_LoadL2SP(); |
||||
void __cdecl DRLG_FreeL2SP(); |
||||
void __fastcall DRLG_L2(int entry); |
||||
bool __fastcall DRLG_L2PlaceMiniSet(unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, int ldir); |
||||
void __fastcall DRLG_L2PlaceRndSet(unsigned char *miniset, int rndper); |
||||
void __cdecl DRLG_L2Subs(); |
||||
void __cdecl DRLG_L2Shadows(); |
||||
void __fastcall DRLG_L2SetRoom(int rx1, int ry1); |
||||
void __cdecl L2TileFix(); |
||||
bool __cdecl CreateDungeon(); |
||||
void __fastcall CreateRoom(int nX1, int nY1, int nX2, int nY2, int nRDest, int nHDir, int ForceHW, int nH, int nW); |
||||
void __fastcall DefineRoom(int nX1, int nY1, int nX2, int nY2, int ForceHW); |
||||
void __fastcall AddHall(int nX1, int nY1, int nX2, int nY2, int nHd); |
||||
void __fastcall GetHall(int *nX1, int *nY1, int *nX2, int *nY2, int *nHd); |
||||
void __fastcall ConnectHall(int nX1, int nY1, int nX2, int nY2, int nHd); |
||||
void __fastcall CreateDoorType(int nX, int nY); |
||||
void __fastcall PlaceHallExt(int nX, int nY); |
||||
void __fastcall DoPatternCheck(int i, int j); |
||||
bool __cdecl DL2_FillVoids(); |
||||
bool __fastcall DL2_Cont(bool x1f, bool y1f, bool x2f, bool y2f); |
||||
int __cdecl DL2_NumNoChar(); |
||||
void __fastcall DL2_DrawRoom(int x1, int y1, int x2, int y2); |
||||
void __fastcall DL2_KnockWalls(int x1, int y1, int x2, int y2); |
||||
void __cdecl DRLG_L2FloodTVal(); |
||||
void __fastcall DRLG_L2FTVR(int i, int j, int x, int y, int d); |
||||
void __cdecl DRLG_L2TransFix(); |
||||
void __cdecl L2DirtFix(); |
||||
void __cdecl DRLG_InitL2Vals(); |
||||
|
||||
/* rdata */ |
||||
extern int Area_Min; // weak
|
||||
extern int Room_Max; // weak
|
||||
extern int Room_Min; // weak
|
||||
extern int Dir_Xadd[5]; |
||||
extern int Dir_Yadd[5]; |
||||
extern ShadowStruct SPATSL2[2]; |
||||
//short word_48489A;
|
||||
extern unsigned char BTYPESL2[161]; |
||||
extern unsigned char BSTYPESL2[161]; |
||||
extern unsigned char VARCH1[]; |
||||
extern unsigned char VARCH2[]; |
||||
extern unsigned char VARCH3[]; |
||||
extern unsigned char VARCH4[]; |
||||
extern unsigned char VARCH5[]; |
||||
extern unsigned char VARCH6[]; |
||||
extern unsigned char VARCH7[]; |
||||
extern unsigned char VARCH8[]; |
||||
extern unsigned char VARCH9[]; |
||||
extern unsigned char VARCH10[]; |
||||
extern unsigned char VARCH11[]; |
||||
extern unsigned char VARCH12[]; |
||||
extern unsigned char VARCH13[]; |
||||
extern unsigned char VARCH14[]; |
||||
extern unsigned char VARCH15[]; |
||||
extern unsigned char VARCH16[]; |
||||
extern unsigned char VARCH17[]; |
||||
extern unsigned char VARCH18[]; |
||||
extern unsigned char VARCH19[]; |
||||
extern unsigned char VARCH20[]; |
||||
extern unsigned char VARCH21[]; |
||||
extern unsigned char VARCH22[]; |
||||
extern unsigned char VARCH23[]; |
||||
extern unsigned char VARCH24[]; |
||||
extern unsigned char VARCH25[]; |
||||
extern unsigned char VARCH26[]; |
||||
extern unsigned char VARCH27[]; |
||||
extern unsigned char VARCH28[]; |
||||
extern unsigned char VARCH29[]; |
||||
extern unsigned char VARCH30[]; |
||||
extern unsigned char VARCH31[]; |
||||
extern unsigned char VARCH32[]; |
||||
extern unsigned char VARCH33[]; |
||||
extern unsigned char VARCH34[]; |
||||
extern unsigned char VARCH35[]; |
||||
extern unsigned char VARCH36[]; |
||||
extern unsigned char VARCH37[]; |
||||
extern unsigned char VARCH38[]; |
||||
extern unsigned char VARCH39[]; |
||||
extern unsigned char VARCH40[]; |
||||
extern unsigned char HARCH1[]; |
||||
extern unsigned char HARCH2[]; |
||||
extern unsigned char HARCH3[]; |
||||
extern unsigned char HARCH4[]; |
||||
extern unsigned char HARCH5[]; |
||||
extern unsigned char HARCH6[]; |
||||
extern unsigned char HARCH7[]; |
||||
extern unsigned char HARCH8[]; |
||||
extern unsigned char HARCH9[]; |
||||
extern unsigned char HARCH10[]; |
||||
extern unsigned char HARCH11[]; |
||||
extern unsigned char HARCH12[]; |
||||
extern unsigned char HARCH13[]; |
||||
extern unsigned char HARCH14[]; |
||||
extern unsigned char HARCH15[]; |
||||
extern unsigned char HARCH16[]; |
||||
extern unsigned char HARCH17[]; |
||||
extern unsigned char HARCH18[]; |
||||
extern unsigned char HARCH19[]; |
||||
extern unsigned char HARCH20[]; |
||||
extern unsigned char HARCH21[]; |
||||
extern unsigned char HARCH22[]; |
||||
extern unsigned char HARCH23[]; |
||||
extern unsigned char HARCH24[]; |
||||
extern unsigned char HARCH25[]; |
||||
extern unsigned char HARCH26[]; |
||||
extern unsigned char HARCH27[]; |
||||
extern unsigned char HARCH28[]; |
||||
extern unsigned char HARCH29[]; |
||||
extern unsigned char HARCH30[]; |
||||
extern unsigned char HARCH31[]; |
||||
extern unsigned char HARCH32[]; |
||||
extern unsigned char HARCH33[]; |
||||
extern unsigned char HARCH34[]; |
||||
extern unsigned char HARCH35[]; |
||||
extern unsigned char HARCH36[]; |
||||
extern unsigned char HARCH37[]; |
||||
extern unsigned char HARCH38[]; |
||||
extern unsigned char HARCH39[]; |
||||
extern unsigned char HARCH40[]; |
||||
extern unsigned char USTAIRS[]; |
||||
extern unsigned char DSTAIRS[]; |
||||
extern unsigned char WARPSTAIRS[]; |
||||
extern unsigned char CRUSHCOL[]; |
||||
extern unsigned char BIG1[]; |
||||
extern unsigned char BIG2[]; |
||||
extern unsigned char BIG3[]; |
||||
extern unsigned char BIG4[]; |
||||
extern unsigned char BIG5[]; |
||||
extern unsigned char BIG6[]; |
||||
extern unsigned char BIG7[]; |
||||
extern unsigned char BIG8[]; |
||||
extern unsigned char BIG9[]; |
||||
extern unsigned char BIG10[]; |
||||
extern unsigned char RUINS1[]; |
||||
extern unsigned char RUINS2[]; |
||||
extern unsigned char RUINS3[]; |
||||
extern unsigned char RUINS4[]; |
||||
extern unsigned char RUINS5[]; |
||||
extern unsigned char RUINS6[]; |
||||
extern unsigned char RUINS7[]; |
||||
extern unsigned char PANCREAS1[]; |
||||
extern unsigned char PANCREAS2[]; |
||||
extern unsigned char CTRDOOR1[]; |
||||
extern unsigned char CTRDOOR2[]; |
||||
extern unsigned char CTRDOOR3[]; |
||||
extern unsigned char CTRDOOR4[]; |
||||
extern unsigned char CTRDOOR5[]; |
||||
extern unsigned char CTRDOOR6[]; |
||||
extern unsigned char CTRDOOR7[]; |
||||
extern unsigned char CTRDOOR8[]; |
||||
extern int Patterns[100][10]; |
||||
|
||||
#endif /* __DRLG_L2_H__ */ |
||||
@ -0,0 +1,87 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DRLG_L3_H__ |
||||
#define __DRLG_L3_H__ |
||||
|
||||
extern char lavapool; // weak
|
||||
extern int abyssx; // weak
|
||||
extern int lockoutcnt; // weak
|
||||
extern char lockout[40][40]; |
||||
|
||||
void __cdecl AddFenceDoors(); |
||||
void __cdecl FenceDoorFix(); |
||||
int __cdecl DRLG_L3Anvil(); |
||||
void __cdecl FixL3Warp(); |
||||
void __cdecl FixL3HallofHeroes(); |
||||
void __fastcall DRLG_L3LockRec(int x, int y); |
||||
bool __cdecl DRLG_L3Lockout(); |
||||
void __fastcall CreateL3Dungeon(int rseed, int entry); |
||||
void __fastcall DRLG_L3(int entry); |
||||
void __cdecl InitL3Dungeon(); |
||||
int __fastcall DRLG_L3FillRoom(int x1, int y1, int x2, int y2); |
||||
void __fastcall DRLG_L3CreateBlock(int x, int y, int obs, int dir); |
||||
void __fastcall DRLG_L3FloorArea(int x1, int y1, int x2, int y2); |
||||
void __cdecl DRLG_L3FillDiags(); |
||||
void __cdecl DRLG_L3FillSingles(); |
||||
void __cdecl DRLG_L3FillStraights(); |
||||
void __cdecl DRLG_L3Edges(); |
||||
int __cdecl DRLG_L3GetFloorArea(); |
||||
void __cdecl DRLG_L3MakeMegas(); |
||||
void __cdecl DRLG_L3River(); |
||||
void __cdecl DRLG_L3Pool(); |
||||
int __fastcall DRLG_L3SpawnEdge(int x, int y, int *totarea); |
||||
int __fastcall DRLG_L3Spawn(int x, int y, int *totarea); |
||||
void __cdecl DRLG_L3PoolFix(); |
||||
int __fastcall DRLG_L3PlaceMiniSet(const unsigned char *miniset, int tmin, int tmax, int cx, int cy, bool setview, int ldir); |
||||
void __fastcall DRLG_L3PlaceRndSet(const unsigned char *miniset, int rndper); |
||||
void __cdecl DRLG_L3Wood(); |
||||
bool __fastcall WoodVertU(int i, int y); |
||||
bool __fastcall WoodVertD(int i, int y); |
||||
bool __fastcall WoodHorizL(int x, int j); |
||||
bool __fastcall WoodHorizR(int x, int j); |
||||
void __cdecl DRLG_L3Pass3(); |
||||
void __fastcall LoadL3Dungeon(char *sFileName, int vx, int vy); |
||||
void __fastcall LoadPreL3Dungeon(char *sFileName, int vx, int vy); |
||||
|
||||
/* rdata */ |
||||
extern const unsigned char L3ConvTbl[16]; |
||||
extern const unsigned char L3UP[20]; |
||||
extern const unsigned char L3DOWN[20]; |
||||
extern const unsigned char L3HOLDWARP[20]; |
||||
extern const unsigned char L3TITE1[34]; |
||||
extern const unsigned char L3TITE2[34]; |
||||
extern const unsigned char L3TITE3[34]; |
||||
extern const unsigned char L3TITE6[42]; |
||||
extern const unsigned char L3TITE7[42]; |
||||
extern const unsigned char L3TITE8[20]; |
||||
extern const unsigned char L3TITE9[20]; |
||||
extern const unsigned char L3TITE10[20]; |
||||
extern const unsigned char L3TITE11[20]; |
||||
extern const unsigned char L3TITE12[6]; |
||||
extern const unsigned char L3TITE13[6]; |
||||
extern const unsigned char L3CREV1[6]; |
||||
extern const unsigned char L3CREV2[6]; |
||||
extern const unsigned char L3CREV3[6]; |
||||
extern const unsigned char L3CREV4[6]; |
||||
extern const unsigned char L3CREV5[6]; |
||||
extern const unsigned char L3CREV6[6]; |
||||
extern const unsigned char L3CREV7[6]; |
||||
extern const unsigned char L3CREV8[6]; |
||||
extern const unsigned char L3CREV9[6]; |
||||
extern const unsigned char L3CREV10[6]; |
||||
extern const unsigned char L3CREV11[6]; |
||||
extern const unsigned char L3ISLE1[14]; |
||||
extern const unsigned char L3ISLE2[14]; |
||||
extern const unsigned char L3ISLE3[14]; |
||||
extern const unsigned char L3ISLE4[14]; |
||||
extern const unsigned char L3ISLE5[10]; |
||||
extern const unsigned char L3XTRA1[4]; |
||||
extern const unsigned char L3XTRA2[4]; |
||||
extern const unsigned char L3XTRA3[4]; |
||||
extern const unsigned char L3XTRA4[4]; |
||||
extern const unsigned char L3XTRA5[4]; |
||||
extern const unsigned char L3ANVIL[244]; |
||||
extern const unsigned char L3SpawnTbl1[15]; /* local spawntable? */ |
||||
extern const unsigned char L3SpawnTbl2[15]; /* local spawntable? */ |
||||
extern const unsigned char L3PoolSub[15]; /* local poolsub? */ |
||||
|
||||
#endif /* __DRLG_L3_H__ */ |
||||
@ -0,0 +1,69 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DRLG_L4_H__ |
||||
#define __DRLG_L4_H__ |
||||
|
||||
extern int diabquad1x; // weak
|
||||
extern int diabquad1y; // weak
|
||||
extern int diabquad3x; // idb
|
||||
extern int diabquad3y; // idb
|
||||
extern int diabquad2x; // idb
|
||||
extern int diabquad2y; // idb
|
||||
extern int diabquad4x; // idb
|
||||
extern int diabquad4y; // idb
|
||||
extern int hallok[20]; |
||||
extern int l4holdx; // weak
|
||||
extern int l4holdy; // weak
|
||||
extern int SP4x1; // idb
|
||||
extern int SP4x2; // weak
|
||||
extern int SP4y1; // idb
|
||||
extern int SP4y2; // weak
|
||||
extern char L4dungeon[80][80]; |
||||
extern char dung[20][20]; |
||||
//int dword_52A4DC; // weak
|
||||
|
||||
void __cdecl DRLG_LoadL4SP(); |
||||
void __cdecl DRLG_FreeL4SP(); |
||||
void __fastcall DRLG_L4SetSPRoom(int rx1, int ry1); |
||||
void __cdecl L4SaveQuads(); |
||||
void __fastcall DRLG_L4SetRoom(unsigned char *pSetPiece, int rx1, int ry1); |
||||
void __fastcall DRLG_LoadDiabQuads(bool preflag); |
||||
bool __fastcall IsDURWall(char d); |
||||
bool __fastcall IsDLLWall(char dd); |
||||
void __cdecl L4FixRim(); |
||||
void __cdecl DRLG_L4GeneralFix(); |
||||
void __fastcall CreateL4Dungeon(int rseed, int entry); |
||||
void __fastcall DRLG_L4(int entry); |
||||
void __cdecl DRLG_L4Shadows(); |
||||
void __cdecl InitL4Dungeon(); |
||||
void __cdecl L4makeDmt(); |
||||
void __cdecl L4AddWall(); |
||||
int __fastcall L4HWallOk(int i, int j); |
||||
int __fastcall L4VWallOk(int i, int j); |
||||
void __fastcall L4HorizWall(int i, int j, int dx); |
||||
void __fastcall L4VertWall(int i, int j, int dy); |
||||
void __cdecl L4tileFix(); |
||||
void __cdecl DRLG_L4Subs(); |
||||
void __cdecl L4makeDungeon(); |
||||
void __cdecl uShape(); |
||||
int __cdecl GetArea(); |
||||
void __cdecl L4firstRoom(); |
||||
void __fastcall L4drawRoom(int x, int y, int width, int height); |
||||
void __fastcall L4roomGen(int x, int y, int w, int h, int dir); |
||||
bool __fastcall L4checkRoom(int x, int y, int width, int height); |
||||
bool __fastcall DRLG_L4PlaceMiniSet(const unsigned char *miniset, int tmin, int tmax, int cx, int cy, int setview, int ldir); |
||||
void __cdecl DRLG_L4FloodTVal(); |
||||
void __fastcall DRLG_L4FTVR(int i, int j, int x, int y, int d); |
||||
void __cdecl DRLG_L4TransFix(); |
||||
void __cdecl DRLG_L4Corners(); |
||||
void __cdecl DRLG_L4Pass3(); |
||||
|
||||
/* rdata */ |
||||
extern const unsigned char L4ConvTbl[16]; |
||||
extern const unsigned char L4USTAIRS[42]; |
||||
extern const unsigned char L4TWARP[42]; |
||||
extern const unsigned char L4DSTAIRS[52]; |
||||
extern const unsigned char L4PENTA[52]; |
||||
extern const unsigned char L4PENTA2[52]; |
||||
extern const unsigned char L4BTYPES[140]; |
||||
|
||||
#endif /* __DRLG_L4_H__ */ |
||||
@ -0,0 +1,200 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
int dthread_cpp_init_value; // weak
|
||||
static CRITICAL_SECTION sgMemCrit; // idb
|
||||
unsigned int glpDThreadId; // idb
|
||||
TMegaPkt *sgpInfoHead; /* may not be right struct */ |
||||
char byte_52A508; // weak
|
||||
HANDLE sghWorkToDoEvent; // idb
|
||||
|
||||
int dthread_inf = 0x7F800000; // weak
|
||||
|
||||
/* rdata */ |
||||
static HANDLE sghThread = (HANDLE)0xFFFFFFFF; // idb
|
||||
|
||||
struct dthread_cpp_init_1 |
||||
{ |
||||
dthread_cpp_init_1() |
||||
{ |
||||
dthread_cpp_init_value = dthread_inf; |
||||
} |
||||
} _dthread_cpp_init_1; |
||||
// 47A460: using guessed type int dthread_inf;
|
||||
// 52A4E0: using guessed type int dthread_cpp_init_value;
|
||||
|
||||
struct dthread_cpp_init_2 |
||||
{ |
||||
dthread_cpp_init_2() |
||||
{ |
||||
dthread_init_mutex(); |
||||
dthread_cleanup_mutex_atexit(); |
||||
} |
||||
} _dthread_cpp_init_2; |
||||
|
||||
void __cdecl dthread_init_mutex() |
||||
{ |
||||
InitializeCriticalSection(&sgMemCrit); |
||||
} |
||||
|
||||
void __cdecl dthread_cleanup_mutex_atexit() |
||||
{ |
||||
atexit(dthread_cleanup_mutex); |
||||
} |
||||
|
||||
void __cdecl dthread_cleanup_mutex() |
||||
{ |
||||
DeleteCriticalSection(&sgMemCrit); |
||||
} |
||||
|
||||
void __fastcall dthread_remove_player(int pnum) |
||||
{ |
||||
int v1; // edi
|
||||
TMegaPkt *i; // eax
|
||||
|
||||
v1 = pnum; |
||||
EnterCriticalSection(&sgMemCrit); |
||||
for ( i = sgpInfoHead; i; i = i->pNext ) |
||||
{ |
||||
if ( i->dwSpaceLeft == v1 ) |
||||
i->dwSpaceLeft = 4; |
||||
} |
||||
LeaveCriticalSection(&sgMemCrit); |
||||
} |
||||
|
||||
void __fastcall dthread_send_delta(int pnum, char cmd, void *pbSrc, int dwLen) |
||||
{ |
||||
TMegaPkt *v5; // eax
|
||||
TMegaPkt *v6; // esi
|
||||
TMegaPkt *v7; // eax
|
||||
TMegaPkt **v8; // ecx
|
||||
int v9; // [esp+4h] [ebp-4h]
|
||||
|
||||
v9 = pnum; |
||||
if ( gbMaxPlayers != 1 ) |
||||
{ |
||||
v5 = (TMegaPkt *)DiabloAllocPtr(dwLen + 20); |
||||
v6 = v5; |
||||
v5->pNext = 0; |
||||
v5->dwSpaceLeft = v9; |
||||
v5->data[0] = cmd; |
||||
*(_DWORD *)&v5->data[4] = dwLen; |
||||
memcpy(&v5->data[8], pbSrc, dwLen); |
||||
EnterCriticalSection(&sgMemCrit); |
||||
v7 = sgpInfoHead; |
||||
v8 = &sgpInfoHead; |
||||
while ( v7 ) |
||||
{ |
||||
v8 = &v7->pNext; |
||||
v7 = v7->pNext; |
||||
} |
||||
*v8 = v6; |
||||
SetEvent(sghWorkToDoEvent); |
||||
LeaveCriticalSection(&sgMemCrit); |
||||
} |
||||
} |
||||
// 679660: using guessed type char gbMaxPlayers;
|
||||
|
||||
void __cdecl dthread_start() |
||||
{ |
||||
char *v0; // eax
|
||||
char *v1; // eax
|
||||
|
||||
if ( gbMaxPlayers != 1 ) |
||||
{ |
||||
sghWorkToDoEvent = CreateEvent(NULL, TRUE, FALSE, NULL); |
||||
if ( !sghWorkToDoEvent ) |
||||
{ |
||||
v0 = TraceLastError(); |
||||
TermMsg("dthread:1\n%s", v0); |
||||
} |
||||
byte_52A508 = 1; |
||||
sghThread = (HANDLE)_beginthreadex(NULL, 0, dthread_handler, NULL, 0, &glpDThreadId); |
||||
if ( sghThread == (HANDLE)-1 ) |
||||
{ |
||||
v1 = TraceLastError(); |
||||
TermMsg("dthread2:\n%s", v1); |
||||
} |
||||
} |
||||
} |
||||
// 52A508: using guessed type char byte_52A508;
|
||||
// 679660: using guessed type char gbMaxPlayers;
|
||||
|
||||
unsigned int __stdcall dthread_handler(void *a1) |
||||
{ |
||||
char *v1; // eax
|
||||
TMegaPkt *v2; // esi
|
||||
int v3; // ecx
|
||||
unsigned int v4; // edi
|
||||
|
||||
while ( byte_52A508 ) |
||||
{ |
||||
if ( !sgpInfoHead && WaitForSingleObject(sghWorkToDoEvent, 0xFFFFFFFF) == -1 ) |
||||
{ |
||||
v1 = TraceLastError(); |
||||
TermMsg("dthread4:\n%s", v1); |
||||
} |
||||
EnterCriticalSection(&sgMemCrit); |
||||
v2 = sgpInfoHead; |
||||
if ( sgpInfoHead ) |
||||
sgpInfoHead = sgpInfoHead->pNext; |
||||
else |
||||
ResetEvent(sghWorkToDoEvent); |
||||
LeaveCriticalSection(&sgMemCrit); |
||||
if ( v2 ) |
||||
{ |
||||
v3 = v2->dwSpaceLeft; |
||||
if ( v3 != 4 ) |
||||
multi_send_zero_packet(v3, v2->data[0], &v2->data[8], *(_DWORD *)&v2->data[4]); |
||||
v4 = 1000 * *(_DWORD *)&v2->data[4] / (unsigned int)gdwDeltaBytesSec; |
||||
if ( v4 >= 1 ) |
||||
v4 = 1; |
||||
mem_free_dbg(v2); |
||||
if ( v4 ) |
||||
Sleep(v4); |
||||
} |
||||
} |
||||
return 0; |
||||
} |
||||
// 52A508: using guessed type char byte_52A508;
|
||||
// 679730: using guessed type int gdwDeltaBytesSec;
|
||||
|
||||
void __cdecl dthread_cleanup() |
||||
{ |
||||
char *v0; // eax
|
||||
TMegaPkt *v1; // eax
|
||||
TMegaPkt *v2; // esi
|
||||
|
||||
if ( sghWorkToDoEvent ) |
||||
{ |
||||
byte_52A508 = 0; |
||||
SetEvent(sghWorkToDoEvent); |
||||
if ( sghThread != (HANDLE)-1 && glpDThreadId != GetCurrentThreadId() ) |
||||
{ |
||||
if ( WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1 ) |
||||
{ |
||||
v0 = TraceLastError(); |
||||
TermMsg("dthread3:\n(%s)", v0); |
||||
} |
||||
CloseHandle(sghThread); |
||||
sghThread = (HANDLE)-1; |
||||
} |
||||
CloseHandle(sghWorkToDoEvent); |
||||
v1 = sgpInfoHead; |
||||
sghWorkToDoEvent = 0; |
||||
if ( sgpInfoHead ) |
||||
{ |
||||
do |
||||
{ |
||||
v2 = v1->pNext; |
||||
sgpInfoHead = 0; |
||||
mem_free_dbg(v1); |
||||
v1 = v2; |
||||
sgpInfoHead = v2; |
||||
} |
||||
while ( v2 ); |
||||
} |
||||
} |
||||
} |
||||
// 52A508: using guessed type char byte_52A508;
|
||||
@ -0,0 +1,25 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DTHREAD_H__ |
||||
#define __DTHREAD_H__ |
||||
|
||||
extern int dthread_cpp_init_value; // weak
|
||||
extern unsigned int glpDThreadId; // idb
|
||||
extern TMegaPkt *sgpInfoHead; /* may not be right struct */ |
||||
extern char byte_52A508; // weak
|
||||
extern HANDLE sghWorkToDoEvent; // idb
|
||||
|
||||
void __cdecl dthread_cpp_init_1(); |
||||
void __cdecl dthread_cpp_init_2(); |
||||
void __cdecl dthread_init_mutex(); |
||||
void __cdecl dthread_cleanup_mutex_atexit(); |
||||
void __cdecl dthread_cleanup_mutex(); |
||||
void __fastcall dthread_remove_player(int pnum); |
||||
void __fastcall dthread_send_delta(int pnum, char cmd, void *pbSrc, int dwLen); |
||||
void __cdecl dthread_start(); |
||||
unsigned int __stdcall dthread_handler(void *a1); |
||||
void __cdecl dthread_cleanup(); |
||||
|
||||
/* data */ |
||||
extern int dthread_inf; // weak
|
||||
|
||||
#endif /* __DTHREAD_H__ */ |
||||
@ -0,0 +1,298 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
void *sgpBackBuf; |
||||
int dx_cpp_init_value; // weak
|
||||
IDirectDraw *lpDDInterface; |
||||
IDirectDrawPalette *lpDDPalette; // idb
|
||||
int sgdwLockCount; |
||||
Screen *gpBuffer; |
||||
IDirectDrawSurface *lpDDSBackBuf; |
||||
IDirectDrawSurface *lpDDSPrimary; |
||||
static CRITICAL_SECTION sgMemCrit; |
||||
char gbBackBuf; // weak
|
||||
char gbEmulate; // weak
|
||||
HMODULE ghDiabMod; // idb
|
||||
|
||||
int dx_inf = 0x7F800000; // weak
|
||||
|
||||
struct dx_cpp_init_1 |
||||
{ |
||||
dx_cpp_init_1() |
||||
{ |
||||
dx_cpp_init_value = dx_inf; |
||||
} |
||||
} _dx_cpp_init_1; |
||||
// 47A464: using guessed type int dx_inf;
|
||||
// 52A514: using guessed type int dx_cpp_init_value;
|
||||
|
||||
struct dx_cpp_init_2 |
||||
{ |
||||
dx_cpp_init_2() |
||||
{ |
||||
dx_init_mutex(); |
||||
dx_cleanup_mutex_atexit(); |
||||
} |
||||
} _dx_cpp_init_2; |
||||
|
||||
void __cdecl dx_init_mutex() |
||||
{ |
||||
InitializeCriticalSection(&sgMemCrit); |
||||
} |
||||
|
||||
void __cdecl dx_cleanup_mutex_atexit() |
||||
{ |
||||
atexit(dx_cleanup_mutex); |
||||
} |
||||
|
||||
void __cdecl dx_cleanup_mutex() |
||||
{ |
||||
DeleteCriticalSection(&sgMemCrit); |
||||
} |
||||
|
||||
void __fastcall dx_init(HWND hWnd) |
||||
{ |
||||
HWND v1; // esi
|
||||
GUID *v2; // ecx
|
||||
int v3; // eax
|
||||
int v4; // eax
|
||||
//int v5; // ecx
|
||||
int v6; // edi
|
||||
int v7; // eax
|
||||
int v8; // eax
|
||||
HWND hWnda; // [esp+1Ch] [ebp-4h]
|
||||
|
||||
v1 = hWnd; |
||||
hWnda = hWnd; |
||||
SetFocus(hWnd); |
||||
ShowWindow(v1, SW_SHOWNORMAL); |
||||
v2 = NULL; |
||||
if ( gbEmulate ) |
||||
v2 = (GUID *)DDCREATE_EMULATIONONLY; |
||||
v3 = dx_DirectDrawCreate(v2, &lpDDInterface, NULL); |
||||
if ( v3 ) |
||||
ErrDlg(IDD_DIALOG1, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 149); |
||||
fullscreen = 1; |
||||
v4 = lpDDInterface->SetCooperativeLevel(v1, DDSCL_EXCLUSIVE|DDSCL_ALLOWREBOOT|DDSCL_FULLSCREEN); |
||||
if ( v4 == DDERR_EXCLUSIVEMODEALREADYSET ) |
||||
{ |
||||
MI_Dummy(0); // v5
|
||||
} |
||||
else if ( v4 ) |
||||
{ |
||||
ErrDlg(IDD_DIALOG1, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 170); |
||||
} |
||||
if ( lpDDInterface->SetDisplayMode(640, 480, 8) ) |
||||
{ |
||||
v6 = GetSystemMetrics(SM_CXSCREEN); |
||||
v7 = GetSystemMetrics(SM_CYSCREEN); |
||||
v8 = lpDDInterface->SetDisplayMode(v6, v7, 8); |
||||
if ( v8 ) |
||||
ErrDlg(IDD_DIALOG1, v8, "C:\\Src\\Diablo\\Source\\dx.cpp", 183); |
||||
} |
||||
dx_create_primary_surface(); |
||||
palette_init(); |
||||
GdiSetBatchLimit(1); |
||||
dx_create_back_buffer(); |
||||
SDrawManualInitialize(hWnda, lpDDInterface, lpDDSPrimary, 0, 0, lpDDSBackBuf, lpDDPalette, 0); |
||||
} |
||||
// 484364: using guessed type int fullscreen;
|
||||
// 52A549: using guessed type char gbEmulate;
|
||||
|
||||
void __cdecl dx_create_back_buffer() |
||||
{ |
||||
int v0; // eax
|
||||
int v1; // eax
|
||||
int v2; // eax
|
||||
int v3; // eax
|
||||
DDSURFACEDESC v4; // [esp+Ch] [ebp-70h]
|
||||
DDSCAPS v5; // [esp+78h] [ebp-4h]
|
||||
|
||||
v0 = lpDDSPrimary->GetCaps(&v5); |
||||
if ( v0 ) |
||||
DDErrMsg(v0, 59, "C:\\Src\\Diablo\\Source\\dx.cpp"); |
||||
if ( !gbBackBuf ) |
||||
{ |
||||
v4.dwSize = 108; |
||||
v1 = lpDDSPrimary->Lock(NULL, &v4, DDLOCK_WRITEONLY|DDLOCK_WAIT, NULL); |
||||
if ( !v1 ) |
||||
{ |
||||
lpDDSPrimary->Unlock(NULL); |
||||
sgpBackBuf = DiabloAllocPtr(0x7B000); |
||||
return; |
||||
} |
||||
if ( v1 != DDERR_CANTLOCKSURFACE ) |
||||
ErrDlg(IDD_DIALOG1, v1, "C:\\Src\\Diablo\\Source\\dx.cpp", 81); |
||||
} |
||||
memset(&v4, 0, 0x6Cu); |
||||
v4.dwWidth = 768; |
||||
v4.lPitch = 768; |
||||
v4.dwSize = 108; |
||||
v4.dwFlags = DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS; |
||||
v4.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN; |
||||
v4.dwHeight = 656; |
||||
v4.ddpfPixelFormat.dwSize = 32; |
||||
v2 = lpDDSPrimary->GetPixelFormat(&v4.ddpfPixelFormat); |
||||
if ( v2 ) |
||||
ErrDlg(IDD_DIALOG1, v2, "C:\\Src\\Diablo\\Source\\dx.cpp", 94); |
||||
v3 = lpDDInterface->CreateSurface(&v4, &lpDDSBackBuf, NULL); |
||||
if ( v3 ) |
||||
ErrDlg(IDD_DIALOG1, v3, "C:\\Src\\Diablo\\Source\\dx.cpp", 96); |
||||
} |
||||
// 52A548: using guessed type char gbBackBuf;
|
||||
|
||||
void __cdecl dx_create_primary_surface() |
||||
{ |
||||
int v0; // eax
|
||||
DDSURFACEDESC v1; // [esp+0h] [ebp-6Ch]
|
||||
|
||||
memset(&v1, 0, 0x6Cu); |
||||
v1.dwSize = 108; |
||||
v1.dwFlags = DDSD_CAPS; |
||||
v1.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; |
||||
v0 = lpDDInterface->CreateSurface(&v1, &lpDDSPrimary, NULL); |
||||
if ( v0 ) |
||||
ErrDlg(IDD_DIALOG1, v0, "C:\\Src\\Diablo\\Source\\dx.cpp", 109); |
||||
} |
||||
|
||||
HRESULT __fastcall dx_DirectDrawCreate(GUID *guid, IDirectDraw **DD, void *unknown) |
||||
{ |
||||
IDirectDraw **v3; // ebp
|
||||
int v4; // eax
|
||||
FARPROC v5; // ebx
|
||||
int v6; // eax
|
||||
GUID *v8; // [esp+10h] [ebp-4h]
|
||||
|
||||
v3 = DD; |
||||
v8 = guid; |
||||
if ( !ghDiabMod ) |
||||
{ |
||||
ghDiabMod = LoadLibrary("ddraw.dll"); |
||||
if ( !ghDiabMod ) |
||||
{ |
||||
v4 = GetLastError(); |
||||
ErrDlg(IDD_DIALOG4, v4, "C:\\Src\\Diablo\\Source\\dx.cpp", 122); |
||||
} |
||||
} |
||||
v5 = GetProcAddress(ghDiabMod, "DirectDrawCreate"); |
||||
if ( !v5 ) |
||||
{ |
||||
v6 = GetLastError(); |
||||
ErrDlg(IDD_DIALOG4, v6, "C:\\Src\\Diablo\\Source\\dx.cpp", 127); |
||||
} |
||||
return ((int (__stdcall *)(GUID *, IDirectDraw **, void *))v5)(v8, v3, unknown); |
||||
} |
||||
|
||||
void __cdecl lock_buf_priv() |
||||
{ |
||||
Screen *v0; // eax
|
||||
int v1; // eax
|
||||
DDSURFACEDESC v2; // [esp+0h] [ebp-6Ch]
|
||||
|
||||
EnterCriticalSection(&sgMemCrit); |
||||
v0 = (Screen *)sgpBackBuf; |
||||
if ( sgpBackBuf ) |
||||
goto LABEL_8; |
||||
if ( lpDDSBackBuf ) |
||||
{ |
||||
if ( sgdwLockCount ) |
||||
goto LABEL_9; |
||||
v2.dwSize = 108; |
||||
v1 = lpDDSBackBuf->Lock(NULL, &v2, DDLOCK_WAIT, NULL); |
||||
if ( v1 ) |
||||
DDErrMsg(v1, 235, "C:\\Src\\Diablo\\Source\\dx.cpp"); |
||||
v0 = (Screen *)v2.lpSurface; |
||||
gpBufEnd += (unsigned int)v2.lpSurface; |
||||
LABEL_8: |
||||
gpBuffer = v0; |
||||
goto LABEL_9; |
||||
} |
||||
Sleep(20000); |
||||
TermMsg("lock_buf_priv"); |
||||
LABEL_9: |
||||
++sgdwLockCount; |
||||
} |
||||
// 69CF0C: using guessed type int gpBufEnd;
|
||||
|
||||
void __cdecl unlock_buf_priv() |
||||
{ |
||||
Screen *v0; // eax
|
||||
int v1; // eax
|
||||
|
||||
if ( !sgdwLockCount ) |
||||
TermMsg("draw main unlock error"); |
||||
if ( !gpBuffer ) |
||||
TermMsg("draw consistency error"); |
||||
if ( !--sgdwLockCount ) |
||||
{ |
||||
v0 = gpBuffer; |
||||
gpBuffer = 0; |
||||
gpBufEnd -= (signed int)v0; |
||||
if ( !sgpBackBuf ) |
||||
{ |
||||
v1 = lpDDSBackBuf->Unlock(NULL); |
||||
if ( v1 ) |
||||
DDErrMsg(v1, 273, "C:\\Src\\Diablo\\Source\\dx.cpp"); |
||||
} |
||||
} |
||||
LeaveCriticalSection(&sgMemCrit); |
||||
} |
||||
// 69CF0C: using guessed type int gpBufEnd;
|
||||
|
||||
void __cdecl dx_cleanup() |
||||
{ |
||||
void *v0; // ecx
|
||||
|
||||
if ( ghMainWnd ) |
||||
ShowWindow(ghMainWnd, SW_HIDE); |
||||
SDrawDestroy(); |
||||
EnterCriticalSection(&sgMemCrit); |
||||
if ( sgpBackBuf ) |
||||
{ |
||||
v0 = sgpBackBuf; |
||||
sgpBackBuf = 0; |
||||
mem_free_dbg(v0); |
||||
} |
||||
else if ( lpDDSBackBuf ) |
||||
{ |
||||
lpDDSBackBuf->Release(); |
||||
lpDDSBackBuf = 0; |
||||
} |
||||
sgdwLockCount = 0; |
||||
gpBuffer = 0; |
||||
LeaveCriticalSection(&sgMemCrit); |
||||
if ( lpDDSPrimary ) |
||||
{ |
||||
lpDDSPrimary->Release(); |
||||
lpDDSPrimary = 0; |
||||
} |
||||
if ( lpDDPalette ) |
||||
{ |
||||
lpDDPalette->Release(); |
||||
lpDDPalette = 0; |
||||
} |
||||
if ( lpDDInterface ) |
||||
{ |
||||
lpDDInterface->Release(); |
||||
lpDDInterface = 0; |
||||
} |
||||
} |
||||
|
||||
void __cdecl dx_reinit() |
||||
{ |
||||
int v0; // esi
|
||||
|
||||
EnterCriticalSection(&sgMemCrit); |
||||
ClearCursor(); |
||||
v0 = sgdwLockCount; |
||||
while ( sgdwLockCount ) |
||||
unlock_buf_priv(); |
||||
dx_cleanup(); |
||||
drawpanflag = 255; |
||||
dx_init(ghMainWnd); |
||||
for ( ; v0; --v0 ) |
||||
lock_buf_priv(); |
||||
LeaveCriticalSection(&sgMemCrit); |
||||
} |
||||
// 52571C: using guessed type int drawpanflag;
|
||||
@ -0,0 +1,38 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __DX_H__ |
||||
#define __DX_H__ |
||||
|
||||
extern void *sgpBackBuf; |
||||
extern int dx_cpp_init_value; // weak
|
||||
extern IDirectDraw *lpDDInterface; |
||||
extern IDirectDrawPalette *lpDDPalette; // idb
|
||||
extern int sgdwLockCount; |
||||
extern Screen *gpBuffer; |
||||
extern IDirectDrawSurface *lpDDSBackBuf; |
||||
extern IDirectDrawSurface *lpDDSPrimary; |
||||
extern char gbBackBuf; // weak
|
||||
extern char gbEmulate; // weak
|
||||
extern HMODULE ghDiabMod; // idb
|
||||
|
||||
void __cdecl dx_cpp_init_1(); |
||||
void __cdecl dx_cpp_init_2(); |
||||
void __cdecl dx_init_mutex(); |
||||
void __cdecl dx_cleanup_mutex_atexit(); |
||||
void __cdecl dx_cleanup_mutex(); |
||||
void __fastcall dx_init(HWND hWnd); |
||||
void __cdecl dx_create_back_buffer(); |
||||
void __cdecl dx_create_primary_surface(); |
||||
HRESULT __fastcall dx_DirectDrawCreate(GUID *guid, IDirectDraw **DD, void *unknown); |
||||
void __cdecl j_lock_buf_priv(); |
||||
void __cdecl lock_buf_priv(); |
||||
void __cdecl j_unlock_buf_priv(); |
||||
void __cdecl unlock_buf_priv(); |
||||
void __cdecl dx_cleanup(); |
||||
void __cdecl dx_reinit(); |
||||
void __cdecl j_dx_reinit(); |
||||
|
||||
/* data */ |
||||
|
||||
extern int dx_inf; // weak
|
||||
|
||||
#endif /* __DX_H__ */ |
||||
@ -0,0 +1,41 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __EFFECTS_H__ |
||||
#define __EFFECTS_H__ |
||||
|
||||
extern int effects_cpp_init_value; // weak
|
||||
extern int sfxdelay; // weak
|
||||
extern int sfxdnum; |
||||
extern void *sfx_stream; |
||||
extern TSFX *sfx_data_cur; |
||||
|
||||
void __cdecl effects_cpp_init(); |
||||
bool __fastcall effect_is_playing(int nSFX); |
||||
void __cdecl sfx_stop(); |
||||
void __fastcall InitMonsterSND(int monst); |
||||
void __cdecl FreeEffects(); |
||||
void __fastcall PlayEffect(int i, int mode); |
||||
int __fastcall calc_snd_position(int x, int y, int *plVolume, int *plPan); |
||||
void __fastcall PlaySFX(int psfx); |
||||
void __fastcall PlaySFX_priv(TSFX *pSFX, char loc, int x, int y); |
||||
void __fastcall stream_play(TSFX *pSFX, int lVolume, int lPan); |
||||
int __fastcall RndSFX(int psfx); |
||||
void __fastcall PlaySfxLoc(int psfx, int x, int y); |
||||
void __cdecl FreeMonsterSnd(); |
||||
void __cdecl sound_stop(); |
||||
void __cdecl sound_update(); |
||||
void __cdecl effects_cleanup_sfx(); |
||||
void __cdecl stream_update(); |
||||
void __fastcall priv_sound_init(int bLoadMask); |
||||
void __cdecl sound_init(); |
||||
void __stdcall effects_play_sound(char *snd_file); |
||||
|
||||
/* rdata */ |
||||
|
||||
extern const int effects_inf; // weak
|
||||
extern const char monster_action_sounds[]; // idb
|
||||
|
||||
/* data */ |
||||
|
||||
extern TSFX sgSFX[NUM_SFX]; |
||||
|
||||
#endif /* __EFFECTS_H__ */ |
||||
@ -0,0 +1,210 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
int encrypt_table[1280]; |
||||
#endif |
||||
|
||||
void __fastcall encrypt_decrypt_block(void *block, int size, int key) // DecryptMPQBlock
|
||||
{ |
||||
unsigned int v3; // edx
|
||||
int v4; // eax
|
||||
unsigned int v5; // edi
|
||||
unsigned int v6; // edx
|
||||
int v7; // eax
|
||||
int v8; // esi
|
||||
|
||||
v3 = (unsigned int)size >> 2; |
||||
v4 = 0xEEEEEEEE; |
||||
if ( v3 ) |
||||
{ |
||||
v5 = v3; |
||||
v6 = key; |
||||
do |
||||
{ |
||||
v7 = encrypt_table[(unsigned char)v6 + 1024] + v4; |
||||
*(_DWORD *)block ^= v7 + v6; |
||||
v8 = *(_DWORD *)block; |
||||
block = (char *)block + 4; |
||||
v4 = 33 * v7 + v8 + 3; |
||||
v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11); |
||||
--v5; |
||||
} |
||||
while ( v5 ); |
||||
} |
||||
} |
||||
|
||||
void __fastcall encrypt_encrypt_block(void *block, int size, int key) // EncryptMPQBlock
|
||||
{ |
||||
unsigned int v3; // edx
|
||||
int v4; // eax
|
||||
unsigned int v5; // edi
|
||||
unsigned int v6; // edx
|
||||
int v7; // eax
|
||||
int v8; // ebx
|
||||
|
||||
v3 = (unsigned int)size >> 2; |
||||
v4 = 0xEEEEEEEE; |
||||
if ( v3 ) |
||||
{ |
||||
v5 = v3; |
||||
v6 = key; |
||||
do |
||||
{ |
||||
v7 = encrypt_table[(unsigned char)v6 + 1024] + v4; |
||||
v8 = *(_DWORD *)block ^ (v7 + v6); |
||||
v4 = 33 * v7 + *(_DWORD *)block + 3; |
||||
*(_DWORD *)block = v8; |
||||
block = (char *)block + 4; |
||||
v6 = ((~v6 << 21) + 0x11111111) | (v6 >> 11); |
||||
--v5; |
||||
} |
||||
while ( v5 ); |
||||
} |
||||
} |
||||
|
||||
int __fastcall encrypt_hash(char *s, int type) // HashStringSlash
|
||||
{ |
||||
int v2; // ebp
|
||||
char *v3; // ebx
|
||||
signed int v4; // esi
|
||||
int v5; // edi
|
||||
int v6; // ST00_4
|
||||
char v7; // al
|
||||
|
||||
v2 = type; |
||||
v3 = s; |
||||
v4 = 0x7FED7FED; |
||||
v5 = 0xEEEEEEEE; |
||||
while ( v3 && *v3 ) |
||||
{ |
||||
v6 = *v3++; |
||||
v7 = toupper(v6); |
||||
v4 = (v5 + v4) ^ encrypt_table[v7 + (v2 << 8)]; |
||||
v5 = v7 + 33 * v5 + v4 + 3; |
||||
} |
||||
return v4; |
||||
} |
||||
|
||||
void __cdecl encrypt_init_lookup_table() // InitScratchSpace
|
||||
{ |
||||
unsigned int v0; // eax
|
||||
int *v1; // edi
|
||||
unsigned int v2; // eax
|
||||
int v3; // ecx
|
||||
signed int v4; // [esp+Ch] [ebp-8h]
|
||||
int *v5; // [esp+10h] [ebp-4h]
|
||||
|
||||
v0 = 0x100001; |
||||
v5 = encrypt_table; |
||||
do |
||||
{ |
||||
v1 = v5; |
||||
v4 = 5; |
||||
do |
||||
{ |
||||
v2 = (125 * v0 + 3) % 0x2AAAAB; |
||||
v3 = (unsigned short)v2 << 16; |
||||
v0 = (125 * v2 + 3) % 0x2AAAAB; |
||||
*v1 = (unsigned short)v0 | v3; |
||||
v1 += 256; |
||||
--v4; |
||||
} |
||||
while ( v4 ); |
||||
++v5; |
||||
} |
||||
while ( (signed int)v5 < (signed int)&encrypt_table[256] ); |
||||
} |
||||
|
||||
int __fastcall encrypt_compress(void *buf, int size) // MPQCompress_PKWare
|
||||
{ |
||||
unsigned char *v2; // ebx
|
||||
unsigned char *v3; // esi
|
||||
int v4; // ecx
|
||||
unsigned char *v5; // edi
|
||||
TDataInfo param; // [esp+Ch] [ebp-20h]
|
||||
unsigned int type; // [esp+20h] [ebp-Ch]
|
||||
unsigned int dsize; // [esp+24h] [ebp-8h]
|
||||
char *ptr; // [esp+28h] [ebp-4h]
|
||||
|
||||
v2 = (unsigned char *)buf; |
||||
v3 = (unsigned char *)size; |
||||
ptr = (char *)DiabloAllocPtr(CMP_BUFFER_SIZE); // 36312
|
||||
v4 = 2 * (_DWORD)v3; |
||||
if ( (unsigned int)(2 * (_DWORD)v3) < 0x2000 ) |
||||
v4 = 0x2000; |
||||
v5 = (unsigned char *)DiabloAllocPtr(v4); |
||||
param.pbInBuffEnd = 0; |
||||
param.pbOutBuffEnd = 0; |
||||
type = 0; |
||||
param.pbInBuff = v2; |
||||
param.pbOutBuff = v5; |
||||
param.pbSize = v3; |
||||
dsize = 4096; |
||||
implode( |
||||
encrypt_pkware_read, |
||||
encrypt_pkware_write, |
||||
ptr, |
||||
¶m, |
||||
&type, |
||||
&dsize); |
||||
if ( param.pbOutBuffEnd < v3 ) |
||||
{ |
||||
memcpy(v2, v5, (size_t)param.pbOutBuffEnd); |
||||
v3 = param.pbOutBuffEnd; |
||||
} |
||||
mem_free_dbg(ptr); |
||||
mem_free_dbg(v5); |
||||
return (int)v3; |
||||
} |
||||
|
||||
unsigned int __cdecl encrypt_pkware_read(char *buf, unsigned int *size, void *param) // ReadPKWare
|
||||
{ |
||||
TDataInfo * pInfo = (TDataInfo *)param; |
||||
int v3; // edi
|
||||
unsigned char *v4; // ecx
|
||||
|
||||
v3 = *size; |
||||
v4 = pInfo->pbInBuffEnd; |
||||
if ( *size >= (unsigned int)(pInfo->pbSize - v4) ) |
||||
v3 = pInfo->pbSize - v4; |
||||
memcpy(buf, &v4[(unsigned int)pInfo->pbInBuff], v3); |
||||
pInfo->pbInBuffEnd += v3; |
||||
return v3; |
||||
} |
||||
|
||||
void __cdecl encrypt_pkware_write(char *buf, unsigned int *size, void *param) // WritePKWare
|
||||
{ |
||||
TDataInfo * pInfo = (TDataInfo *)param; |
||||
|
||||
memcpy(&pInfo->pbOutBuffEnd[(unsigned int)pInfo->pbOutBuff], buf, *size); |
||||
pInfo->pbOutBuffEnd += *size; |
||||
} |
||||
|
||||
void __fastcall encrypt_decompress(void *param, int recv_size, int dwMaxBytes) // MPQDecompress_PKWare
|
||||
{ |
||||
unsigned char *v3; // edi
|
||||
unsigned char *v4; // ebx
|
||||
unsigned char *v5; // esi
|
||||
TDataInfo info; // [esp+Ch] [ebp-18h]
|
||||
char *ptr; // [esp+20h] [ebp-4h]
|
||||
|
||||
v3 = (unsigned char *)param; |
||||
v4 = (unsigned char *)recv_size; |
||||
ptr = (char *)DiabloAllocPtr(CMP_BUFFER_SIZE); // 36312
|
||||
v5 = (unsigned char *)DiabloAllocPtr(dwMaxBytes); |
||||
info.pbInBuffEnd = 0; |
||||
info.pbOutBuffEnd = 0; |
||||
info.pbInBuff = v3; |
||||
info.pbOutBuff = v5; |
||||
info.pbSize = v4; |
||||
explode( |
||||
encrypt_pkware_read, |
||||
encrypt_pkware_write, |
||||
ptr, |
||||
&info); |
||||
memcpy(v3, v5, (size_t)info.pbOutBuffEnd); |
||||
mem_free_dbg(ptr); |
||||
mem_free_dbg(v5); |
||||
} |
||||
@ -0,0 +1,17 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __ENCRYPT_H__ |
||||
#define __ENCRYPT_H__ |
||||
|
||||
extern int encrypt_table[1280]; |
||||
//int encrypt_52B564[257];
|
||||
|
||||
void __fastcall encrypt_decrypt_block(void *block, int size, int key); |
||||
void __fastcall encrypt_encrypt_block(void *block, int size, int key); |
||||
int __fastcall encrypt_hash(char *s, int type); |
||||
void __cdecl encrypt_init_lookup_table(); |
||||
int __fastcall encrypt_compress(void *buf, int size); |
||||
unsigned int __cdecl encrypt_pkware_read(char *buf, unsigned int *size, void *param); |
||||
void __cdecl encrypt_pkware_write(char *buf, unsigned int *size, void *param); |
||||
void __fastcall encrypt_decompress(void *param, int recv_size, int dwMaxBytes); |
||||
|
||||
#endif /* __ENCRYPT_H__ */ |
||||
@ -0,0 +1,80 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __ENGINE_H__ |
||||
#define __ENGINE_H__ |
||||
|
||||
//offset 0
|
||||
//pCelBuff->pFrameTable[0]
|
||||
|
||||
extern int engine_cpp_init_value; // weak
|
||||
extern char gbPixelCol; // automap pixel color 8-bit (palette entry)
|
||||
extern int dword_52B970; // bool flip - if y < x
|
||||
extern int orgseed; // weak
|
||||
extern int sgnWidth; |
||||
extern int sglGameSeed; // weak
|
||||
extern int SeedCount; // weak
|
||||
extern int dword_52B99C; // bool valid - if x/y are in bounds
|
||||
|
||||
void __cdecl engine_cpp_init_1(); |
||||
void __fastcall CelDrawDatOnly(char *pDecodeTo, char *pRLEBytes, int dwRLESize, int dwRLEWdt); |
||||
void __fastcall CelDecodeOnly(int screen_x, int screen_y, void *pCelBuff, int frame, int frame_width); |
||||
void __fastcall CelDecDatOnly(char *pBuff, char *pCelBuff, int frame, int frame_width); |
||||
void __fastcall CelDrawHdrOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction); |
||||
void __fastcall CelDecodeHdrOnly(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction); |
||||
void __fastcall CelDecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); |
||||
void __fastcall CelDecDatLightEntry(unsigned char shift, char *LightIndex, char *&pDecodeTo, char *&pRLEBytes); /* __usercall a1@<cl> a2@<ebx> a3@<edi> a4@<esi> */ |
||||
void __fastcall CelDecDatLightTrans(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); |
||||
void __fastcall CelDecodeLightOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width); |
||||
void __fastcall CelDecodeHdrLightOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction); |
||||
void __fastcall CelDecodeHdrLightTrans(char *pBuff, char *pCelBuff, int frame, int frame_width, int always_0, int direction); |
||||
void __fastcall CelDrawHdrLightRed(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1); |
||||
void __fastcall Cel2DecDatOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); |
||||
void __fastcall Cel2DrawHdrOnly(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction); |
||||
void __fastcall Cel2DecodeHdrOnly(char *pBuff, char *pCelBuff, int frame, int frame_width, int a5, int direction); |
||||
void __fastcall Cel2DecDatLightOnly(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); |
||||
void __fastcall Cel2DecDatLightEntry(unsigned char shift, char *LightIndex, char *&pDecodeTo, char *&pRLEBytes); /* __usercall a1@<cl> a2@<ebx> a3@<edi> a4@<esi> */ |
||||
void __fastcall Cel2DecDatLightTrans(char *pDecodeTo, char *pRLEBytes, int frame_content_size, int frame_width); |
||||
void __fastcall Cel2DecodeHdrLight(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a6, int direction); |
||||
void __fastcall Cel2DecodeLightTrans(char *dst_buf, char *pCelBuff, int frame, int frame_width, int a5, int direction); |
||||
void __fastcall Cel2DrawHdrLightRed(int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int always_0, int direction, char always_1); |
||||
void __fastcall CelDecodeRect(char *pBuff, int always_0, int dst_height, int dst_width, char *pCelBuff, int frame, int frame_width); |
||||
void __fastcall CelDecodeClr(BYTE colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction); |
||||
void __fastcall CelDrawHdrClrHL(char colour, int screen_x, int screen_y, char *pCelBuff, int frame, int frame_width, int a7, int direction); |
||||
void __fastcall ENG_set_pixel(int screen_x, int screen_y, char pixel); |
||||
void __fastcall engine_draw_pixel(int x, int y); |
||||
void __fastcall DrawLine(int x0, int y0, int x1, int y1, char col); |
||||
int __fastcall GetDirection(int x1, int y1, int x2, int y2); |
||||
void __fastcall SetRndSeed(int s); |
||||
int __cdecl GetRndSeed(); |
||||
int __fastcall random(BYTE idx, int v); |
||||
void __cdecl engine_cpp_init_2(); |
||||
void __cdecl mem_init_mutex(); |
||||
void __cdecl mem_atexit_mutex(); |
||||
void __cdecl mem_free_mutex(); |
||||
unsigned char *__fastcall DiabloAllocPtr(int dwBytes); |
||||
void __fastcall mem_free_dbg(void *p); |
||||
unsigned char *__fastcall LoadFileInMem(char *pszName, int *pdwFileLen); |
||||
void __fastcall LoadFileWithMem(char *pszName, void *buf); |
||||
void __fastcall Cl2ApplyTrans(unsigned char *p, unsigned char *ttbl, int last_frame); |
||||
void __fastcall Cl2DecodeFrm1(int x, int y, char *pCelBuff, int nCel, int width, int dir1, int dir2); |
||||
void __fastcall Cl2DecDatFrm1(char *buffer, char *frame_content, int a3, int width); |
||||
void __fastcall Cl2DecodeFrm2(char colour, int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a7, int a8); |
||||
void __fastcall Cl2DecDatFrm2(char *buffer, char *a2, int a3, int a4, char a5); |
||||
void __fastcall Cl2DecodeFrm3(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7, char a8); |
||||
void __fastcall Cl2DecDatLightTbl1(char *a1, char *a2, int a3, int a4, char *unused_lindex); |
||||
void __fastcall Cl2DecodeLightTbl(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7); |
||||
void __fastcall Cl2DecodeFrm4(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7); |
||||
void __fastcall Cl2DecDatFrm4(char *buffer, char *a2, int a3, int frame_width); |
||||
void __fastcall Cl2DecodeClrHL(char colour, int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a7, int a8); |
||||
void __fastcall Cl2DecDatClrHL(char *dst_buf, char *frame_content, int a3, int frame_width, char colour); |
||||
void __fastcall Cl2DecodeFrm5(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7, char a8); |
||||
void __fastcall Cl2DecDatLightTbl2(char *dst_buf, char *a2, int a3, int frame_width, char *a5); |
||||
void __fastcall Cl2DecodeFrm6(int screen_x, int screen_y, char *pCelBuff, int nCel, int frame_width, int a6, int a7); |
||||
void __fastcall PlayInGameMovie(char *pszMovie); |
||||
|
||||
/* rdata */ |
||||
|
||||
extern const int engine_inf; // weak
|
||||
extern const int rand_increment; // unused
|
||||
extern const int rand_multiplier; // unused
|
||||
|
||||
#endif /* __ENGINE_H__ */ |
||||
@ -0,0 +1,217 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
char msgtable[80]; |
||||
char msgdelay; // weak
|
||||
char msgflag; // weak
|
||||
char msgcnt; // weak
|
||||
#endif |
||||
|
||||
char *MsgStrings[44] = |
||||
{ |
||||
&empty_string, |
||||
"No automap available in town", |
||||
"No multiplayer functions in demo", |
||||
"Direct Sound Creation Failed", |
||||
"Not available in shareware version", |
||||
"Not enough space to save", |
||||
"No Pause in town", |
||||
"Copying to a hard disk is recommended", |
||||
"Multiplayer sync problem", |
||||
"No pause in multiplayer", |
||||
"Loading...", |
||||
"Saving...", |
||||
"Some are weakened as one grows strong", |
||||
"New strength is forged through destruction", |
||||
"Those who defend seldom attack", |
||||
"The sword of justice is swift and sharp", |
||||
"While the spirit is vigilant the body thrives", |
||||
"The powers of mana refocused renews", |
||||
"Time cannot diminish the power of steel", |
||||
"Magic is not always what it seems to be", |
||||
"What once was opened now is closed", |
||||
"Intensity comes at the cost of wisdom", |
||||
"Arcane power brings destruction", |
||||
"That which cannot be held cannot be harmed", |
||||
"Crimson and Azure become as the sun", |
||||
"Knowledge and wisdom at the cost of self", |
||||
"Drink and be refreshed", |
||||
"Wherever you go, there you are", |
||||
"Energy comes at the cost of wisdom", |
||||
"Riches abound when least expected", |
||||
"Where avarice fails, patience gains reward", |
||||
"Blessed by a benevolent companion!", |
||||
"The hands of men may be guided by fate", |
||||
"Strength is bolstered by heavenly faith", |
||||
"The essence of life flows from within", |
||||
"The way is made clear when viewed from above", |
||||
"Salvation comes at the cost of wisdom", |
||||
"Mysteries are revealed in the light of reason", |
||||
"Those who are last may yet be first", |
||||
"Generosity brings its own rewards", |
||||
"You must be at least level 8 to use this.", |
||||
"You must be at least level 13 to use this.", |
||||
"You must be at least level 17 to use this.", |
||||
"Arcane knowledge gained!" |
||||
}; |
||||
|
||||
void __fastcall InitDiabloMsg(char e) |
||||
{ |
||||
int i; // edx
|
||||
bool v2; // sf
|
||||
unsigned char v3; // of
|
||||
|
||||
i = 0; |
||||
if ( msgcnt <= 0 ) |
||||
{ |
||||
LABEL_4: |
||||
v3 = __OFSUB__(msgcnt, 80); |
||||
v2 = (char)(msgcnt - 80) < 0; |
||||
msgtable[msgcnt] = e; |
||||
if ( v2 ^ v3 ) |
||||
++msgcnt; |
||||
msgdelay = 70; |
||||
msgflag = msgtable[0]; |
||||
} |
||||
else |
||||
{ |
||||
while ( msgtable[i] != e ) |
||||
{ |
||||
if ( ++i >= msgcnt ) |
||||
goto LABEL_4; |
||||
} |
||||
} |
||||
} |
||||
// 52B9F0: using guessed type char msgdelay;
|
||||
// 52B9F1: using guessed type char msgflag;
|
||||
// 52B9F2: using guessed type char msgcnt;
|
||||
|
||||
void __cdecl ClrDiabloMsg() |
||||
{ |
||||
msgflag = 0; |
||||
msgcnt = 0; |
||||
memset(msgtable, 0, sizeof(msgtable)); |
||||
} |
||||
// 52B9F1: using guessed type char msgflag;
|
||||
// 52B9F2: using guessed type char msgcnt;
|
||||
|
||||
void __cdecl DrawDiabloMsg() |
||||
{ |
||||
int v0; // esi
|
||||
signed int v1; // edi
|
||||
char *v2; // edi
|
||||
signed int v3; // edx
|
||||
signed int v4; // ecx
|
||||
int v5; // edi
|
||||
signed int v6; // ecx
|
||||
_BYTE *v7; // edi
|
||||
int v8; // edi
|
||||
signed int v9; // ebx
|
||||
signed int v10; // eax
|
||||
signed int v11; // ecx
|
||||
int v12; // esi
|
||||
signed int v13; // esi
|
||||
unsigned char v14; // bl
|
||||
bool v15; // zf
|
||||
signed int v16; // [esp+Ch] [ebp-8h]
|
||||
signed int v17; // [esp+Ch] [ebp-8h]
|
||||
signed int screen_x; // [esp+10h] [ebp-4h]
|
||||
|
||||
CelDecodeOnly(165, 318, pSTextSlidCels, 1, 12); |
||||
CelDecodeOnly(591, 318, pSTextSlidCels, 4, 12); |
||||
CelDecodeOnly(165, 366, pSTextSlidCels, 2, 12); |
||||
CelDecodeOnly(591, 366, pSTextSlidCels, 3, 12); |
||||
screen_x = 173; |
||||
v16 = 35; |
||||
do |
||||
{ |
||||
CelDecodeOnly(screen_x, 318, pSTextSlidCels, 5, 12); |
||||
CelDecodeOnly(screen_x, 366, pSTextSlidCels, 7, 12); |
||||
screen_x += 12; |
||||
--v16; |
||||
} |
||||
while ( v16 ); |
||||
v0 = 330; |
||||
v1 = 3; |
||||
do |
||||
{ |
||||
CelDecodeOnly(165, v0, pSTextSlidCels, 6, 12); |
||||
CelDecodeOnly(591, v0, pSTextSlidCels, 8, 12); |
||||
v0 += 12; |
||||
--v1; |
||||
} |
||||
while ( v1 ); |
||||
v2 = &gpBuffer->row[203].pixels[104]; |
||||
v3 = 27; |
||||
do |
||||
{ |
||||
v4 = 216; |
||||
do |
||||
{ |
||||
*v2 = 0; |
||||
v2 += 2; |
||||
--v4; |
||||
} |
||||
while ( v4 ); |
||||
v5 = (int)(v2 - 1200); |
||||
v6 = 216; |
||||
do |
||||
{ |
||||
v7 = (_BYTE *)(v5 + 1); |
||||
*v7 = 0; |
||||
v5 = (int)(v7 + 1); |
||||
--v6; |
||||
} |
||||
while ( v6 ); |
||||
v2 = (char *)(v5 - 1200); |
||||
--v3; |
||||
} |
||||
while ( v3 ); |
||||
strcpy(tempstr, MsgStrings[msgflag]); |
||||
v8 = screen_y_times_768[342] + 165; |
||||
v9 = strlen(tempstr); |
||||
v10 = 0; |
||||
v11 = 0; |
||||
v17 = v9; |
||||
if ( v9 <= 0 ) |
||||
goto LABEL_27; |
||||
do |
||||
{ |
||||
v12 = (unsigned char)tempstr[v11++]; |
||||
v10 += fontkern[fontframe[fontidx[v12]]] + 1; |
||||
} |
||||
while ( v11 < v9 ); |
||||
if ( v10 < 442 ) |
||||
LABEL_27: |
||||
v8 += (442 - v10) >> 1; |
||||
v13 = 0; |
||||
if ( v9 > 0 ) |
||||
{ |
||||
do |
||||
{ |
||||
v14 = fontframe[fontidx[(unsigned char)tempstr[v13]]]; |
||||
if ( v14 ) |
||||
CPrintString(v8, v14, 3); |
||||
++v13; |
||||
v8 += fontkern[v14] + 1; |
||||
} |
||||
while ( v13 < v17 ); |
||||
} |
||||
v15 = msgdelay == 0; |
||||
if ( msgdelay > 0 ) |
||||
v15 = --msgdelay == 0; |
||||
if ( v15 ) |
||||
{ |
||||
v15 = msgcnt-- == 1; |
||||
msgdelay = 70; |
||||
if ( v15 ) |
||||
msgflag = 0; |
||||
else |
||||
msgflag = msgtable[msgcnt]; |
||||
} |
||||
} |
||||
// 52B9F0: using guessed type char msgdelay;
|
||||
// 52B9F1: using guessed type char msgflag;
|
||||
// 52B9F2: using guessed type char msgcnt;
|
||||
@ -0,0 +1,17 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __ERROR_H__ |
||||
#define __ERROR_H__ |
||||
|
||||
extern char msgtable[80]; |
||||
extern char msgdelay; // weak
|
||||
extern char msgflag; // weak
|
||||
extern char msgcnt; // weak
|
||||
|
||||
void __fastcall InitDiabloMsg(char e); |
||||
void __cdecl ClrDiabloMsg(); |
||||
void __cdecl DrawDiabloMsg(); |
||||
|
||||
/* data */ |
||||
extern char *MsgStrings[44]; |
||||
|
||||
#endif /* __ERROR_H__ */ |
||||
@ -0,0 +1,248 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb
|
||||
|
||||
struct exception_cpp_init |
||||
{ |
||||
exception_cpp_init() |
||||
{ |
||||
exception_install_filter(); |
||||
j_exception_init_filter(); |
||||
} |
||||
} _exception_cpp_init; |
||||
|
||||
void __cdecl exception_install_filter() |
||||
{ |
||||
exception_set_filter(); |
||||
} |
||||
|
||||
void __cdecl j_exception_init_filter() |
||||
{ |
||||
atexit(exception_init_filter); |
||||
} |
||||
|
||||
void __cdecl exception_init_filter() |
||||
{ |
||||
exception_set_filter_ptr(); |
||||
} |
||||
|
||||
LONG __stdcall TopLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo) |
||||
{ |
||||
log_dump_computer_info(); |
||||
PEXCEPTION_RECORD xcpt = ExceptionInfo->ExceptionRecord; |
||||
|
||||
char szExceptionNameBuf[MAX_PATH]; // [esp+Ch] [ebp-210h]
|
||||
char *pszExceptionName = exception_get_error_type(ExceptionInfo->ExceptionRecord->ExceptionCode, szExceptionNameBuf, sizeof(szExceptionNameBuf)); |
||||
log_printf("Exception code: %08X %s\r\n", xcpt->ExceptionCode, pszExceptionName); |
||||
|
||||
char szModuleName[MAX_PATH]; |
||||
int sectionNumber, sectionOffset; |
||||
exception_unknown_module(xcpt->ExceptionAddress, szModuleName, MAX_PATH, §ionNumber, §ionOffset); |
||||
log_printf("Fault address:\t%08X %02X:%08X %s\r\n", xcpt->ExceptionAddress, sectionNumber, sectionOffset, szModuleName); |
||||
|
||||
PCONTEXT ctx = ExceptionInfo->ContextRecord; |
||||
|
||||
log_printf("\r\nRegisters:\r\n"); |
||||
log_printf( |
||||
"EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n", |
||||
ctx->Eax, |
||||
ctx->Ebx, |
||||
ctx->Ecx, |
||||
ctx->Edx, |
||||
ctx->Esi, |
||||
ctx->Edi); |
||||
log_printf("CS:EIP:%04X:%08X\r\n", ctx->SegCs, ctx->Eip); |
||||
log_printf("SS:ESP:%04X:%08X EBP:%08X\r\n", ctx->SegSs, ctx->Esp, ctx->Ebp); |
||||
log_printf("DS:%04X ES:%04X FS:%04X GS:%04X\r\n", ctx->SegDs, ctx->SegEs, ctx->SegFs, ctx->SegGs); |
||||
|
||||
log_printf("Flags:%08X\r\n", ctx->EFlags); |
||||
exception_call_stack((void *)ctx->Eip, (STACK_FRAME*)ctx->Ebp); |
||||
|
||||
log_printf("Stack bytes:\r\n"); |
||||
exception_hex_format((BYTE *)ctx->Esp, 0); |
||||
|
||||
log_printf("Code bytes:\r\n"); |
||||
exception_hex_format((BYTE *)ctx->Eip, 16); |
||||
|
||||
log_printf("\r\n"); |
||||
log_flush(1); |
||||
|
||||
if ( lpTopLevelExceptionFilter ) |
||||
return lpTopLevelExceptionFilter(ExceptionInfo); |
||||
return EXCEPTION_CONTINUE_SEARCH; |
||||
} |
||||
|
||||
void __fastcall exception_hex_format(BYTE *ptr, unsigned int numBytes) |
||||
{ |
||||
int i; |
||||
|
||||
while (numBytes > 0) |
||||
{ |
||||
unsigned int bytesRead = 16; |
||||
if (numBytes < 16 ) |
||||
bytesRead = numBytes; |
||||
|
||||
if ( IsBadReadPtr(ptr, bytesRead) ) |
||||
break; |
||||
|
||||
log_printf("0x%08x: ", ptr); |
||||
|
||||
for (i = 0; i < 16; ++i) |
||||
{ |
||||
const char *fmt = "%02x "; |
||||
if (i >= bytesRead) |
||||
fmt = " "; |
||||
log_printf(fmt, ptr[i]); |
||||
if (i % 4 == 3) |
||||
log_printf(" "); |
||||
} |
||||
|
||||
for (i = 0; i < bytesRead; ++i) |
||||
{ |
||||
char c; |
||||
if (isprint(ptr[i])) |
||||
c = ptr[i]; |
||||
else |
||||
c = '.'; |
||||
log_printf("%c", c); |
||||
} |
||||
|
||||
log_printf("\r\n"); |
||||
ptr += bytesRead; |
||||
numBytes -= bytesRead; |
||||
} |
||||
log_printf("\r\n"); |
||||
} |
||||
|
||||
void __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpModuleName, int iMaxLength, int *sectionNum, int *sectionOffset) |
||||
{ |
||||
lstrcpyn(lpModuleName, "*unknown*", iMaxLength); |
||||
*sectionNum = 0; |
||||
*sectionOffset = 0; |
||||
|
||||
MEMORY_BASIC_INFORMATION memInfo; // [esp+Ch] [ebp-24h]
|
||||
if (!VirtualQuery(lpAddress, &memInfo, sizeof(memInfo))) |
||||
return; |
||||
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)memInfo.AllocationBase; |
||||
if ( !memInfo.AllocationBase ) |
||||
dosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(0); |
||||
|
||||
if (!GetModuleFileName((HMODULE)dosHeader, lpModuleName, iMaxLength)) |
||||
{ |
||||
lstrcpyn(lpModuleName, "*unknown*", iMaxLength); |
||||
return; |
||||
} |
||||
|
||||
if (dosHeader && dosHeader->e_magic == IMAGE_DOS_SIGNATURE) |
||||
{ |
||||
LONG ntOffset = dosHeader->e_lfanew; |
||||
if (ntOffset) |
||||
{ |
||||
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + ntOffset); |
||||
if (ntHeader->Signature == IMAGE_NT_SIGNATURE) |
||||
{ |
||||
DWORD numSections = ntHeader->FileHeader.NumberOfSections; |
||||
DWORD moduleOffset = (_BYTE *)lpAddress - (_BYTE *)dosHeader; |
||||
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntHeader); |
||||
for (int i = 0; i < numSections; ++i, ++section) |
||||
{ |
||||
DWORD sectionSize = section->SizeOfRawData; |
||||
DWORD sectionAddress = section->VirtualAddress; |
||||
if (section->SizeOfRawData <= section->Misc.VirtualSize) |
||||
sectionSize = section->Misc.VirtualSize; |
||||
|
||||
if (moduleOffset >= sectionAddress && moduleOffset <= sectionAddress + sectionSize) |
||||
{ |
||||
*sectionNum = i + 1; |
||||
*sectionOffset = moduleOffset - sectionAddress; |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
void __fastcall exception_call_stack(void *instr, STACK_FRAME *stackFrame) |
||||
{ |
||||
STACK_FRAME *oldStackFrame; |
||||
|
||||
log_printf("Call stack:\r\nAddress Frame Logical addr Module\r\n"); |
||||
do |
||||
{ |
||||
char szModuleName[MAX_PATH]; |
||||
int sectionNumber, sectionOffset; |
||||
exception_unknown_module(instr, szModuleName, MAX_PATH, §ionNumber, §ionOffset); |
||||
log_printf("%08X %08X %04X:%08X %s\r\n", instr, stackFrame, sectionNumber, sectionOffset, szModuleName); |
||||
|
||||
if ( IsBadWritePtr(stackFrame, 8u) ) |
||||
break; |
||||
|
||||
instr = stackFrame->pCallRet; |
||||
oldStackFrame = stackFrame; |
||||
stackFrame = stackFrame->pNext; |
||||
|
||||
if ((int)stackFrame % 4 != 0) |
||||
break; |
||||
} |
||||
while (stackFrame > oldStackFrame && !IsBadWritePtr(stackFrame, 8u) ); |
||||
|
||||
log_printf("\r\n"); |
||||
} |
||||
|
||||
#define CASE_EXCEPTION(v, errName) case EXCEPTION_ ## errName: v = #errName; break; |
||||
char *__fastcall exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize) |
||||
{ |
||||
const char *v4; // eax
|
||||
|
||||
switch (dwMessageId) { |
||||
CASE_EXCEPTION(v4, STACK_OVERFLOW); |
||||
CASE_EXCEPTION(v4, FLT_DIVIDE_BY_ZERO); |
||||
CASE_EXCEPTION(v4, FLT_INEXACT_RESULT); |
||||
CASE_EXCEPTION(v4, FLT_INVALID_OPERATION); |
||||
CASE_EXCEPTION(v4, FLT_OVERFLOW); |
||||
CASE_EXCEPTION(v4, FLT_STACK_CHECK); |
||||
CASE_EXCEPTION(v4, FLT_UNDERFLOW); |
||||
CASE_EXCEPTION(v4, INT_DIVIDE_BY_ZERO); |
||||
CASE_EXCEPTION(v4, INT_OVERFLOW); |
||||
CASE_EXCEPTION(v4, PRIV_INSTRUCTION); |
||||
CASE_EXCEPTION(v4, FLT_DENORMAL_OPERAND); |
||||
CASE_EXCEPTION(v4, INVALID_HANDLE); |
||||
CASE_EXCEPTION(v4, ILLEGAL_INSTRUCTION); |
||||
CASE_EXCEPTION(v4, NONCONTINUABLE_EXCEPTION); |
||||
CASE_EXCEPTION(v4, INVALID_DISPOSITION); |
||||
CASE_EXCEPTION(v4, ARRAY_BOUNDS_EXCEEDED); |
||||
CASE_EXCEPTION(v4, IN_PAGE_ERROR); |
||||
CASE_EXCEPTION(v4, GUARD_PAGE); |
||||
CASE_EXCEPTION(v4, DATATYPE_MISALIGNMENT); |
||||
CASE_EXCEPTION(v4, BREAKPOINT); |
||||
CASE_EXCEPTION(v4, SINGLE_STEP); |
||||
CASE_EXCEPTION(v4, ACCESS_VIOLATION); |
||||
default: |
||||
HMODULE ntdll = GetModuleHandle("NTDLL.DLL"); |
||||
if (!FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, ntdll, dwMessageId, 0, lpString1, nSize, NULL)) |
||||
{ |
||||
v4 = "*unknown*"; |
||||
} |
||||
} |
||||
lstrcpyn(lpString1, v4, nSize); |
||||
return lpString1; |
||||
} |
||||
|
||||
void __fastcall exception_set_filter() |
||||
{ |
||||
lpTopLevelExceptionFilter = SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)TopLevelExceptionFilter); |
||||
} |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_set_filter_ptr() |
||||
{ |
||||
return SetUnhandledExceptionFilter(lpTopLevelExceptionFilter); |
||||
} |
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_get_filter() |
||||
{ |
||||
return lpTopLevelExceptionFilter; |
||||
} |
||||
@ -0,0 +1,26 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __FAULT_H__ |
||||
#define __FAULT_H__ |
||||
|
||||
struct STACK_FRAME { |
||||
STACK_FRAME *pNext; |
||||
void *pCallRet; |
||||
}; |
||||
|
||||
//int dword_52B9F4;
|
||||
extern LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter; // idb
|
||||
|
||||
void __cdecl exception_cpp_init(); |
||||
void __cdecl exception_install_filter(); |
||||
void __cdecl j_exception_init_filter(); |
||||
void __cdecl exception_init_filter(); |
||||
LONG __stdcall TopLevelExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo); |
||||
void __fastcall exception_hex_format(BYTE *ptr, unsigned int numBytes); |
||||
void __fastcall exception_unknown_module(LPCVOID lpAddress, LPSTR lpModuleName, int iMaxLength, int *sectionNum, int *sectionOffset); |
||||
void __fastcall exception_call_stack(void *instr, STACK_FRAME *stackAddr); |
||||
char *__fastcall exception_get_error_type(DWORD dwMessageId, LPSTR lpString1, DWORD nSize); |
||||
void __fastcall exception_set_filter(); |
||||
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_set_filter_ptr(); |
||||
LPTOP_LEVEL_EXCEPTION_FILTER __cdecl exception_get_filter(); |
||||
|
||||
#endif /* __FAULT_H__ */ |
||||
@ -0,0 +1,327 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
TMenuItem sgSingleMenu[6] = |
||||
{ |
||||
{ 0x80000000, "Save Game", &gamemenu_save_game }, |
||||
{ 0x80000000, "Options", &gamemenu_options }, |
||||
{ 0x80000000, "New Game", &gamemenu_new_game }, |
||||
{ 0x80000000, "Load Game", &gamemenu_load_game }, |
||||
{ 0x80000000, "Quit Diablo", &gamemenu_quit_game }, |
||||
{ 0x80000000, NULL, NULL } |
||||
}; |
||||
TMenuItem sgMultiMenu[5] = |
||||
{ |
||||
{ 0x80000000, "Options", &gamemenu_options }, |
||||
{ 0x80000000, "New Game", &gamemenu_new_game }, |
||||
{ 0x80000000, "Restart In Town", &gamemenu_restart_town }, |
||||
{ 0x80000000, "Quit Diablo", &gamemenu_quit_game }, |
||||
{ 0x80000000, NULL, NULL } |
||||
}; |
||||
TMenuItem sgOptionMenu[6] = |
||||
{ |
||||
{ 0xC0000000, NULL, (void (__cdecl *)(void))&gamemenu_music_volume }, |
||||
{ 0xC0000000, NULL, (void (__cdecl *)(void))&gamemenu_sound_volume }, |
||||
{ 0xC0000000, "Gamma", (void (__cdecl *)(void))&gamemenu_gamma }, |
||||
{ 0x80000000, NULL, &gamemenu_color_cycling }, |
||||
{ 0x80000000, "Previous Menu", &gamemenu_previous }, |
||||
{ 0x80000000, NULL, NULL } |
||||
}; |
||||
char *music_toggle_names[] = { "Music", "Music Disabled" }; |
||||
char *sound_toggle_names[] = { "Sound", "Sound Disabled" }; |
||||
char *color_cycling_toggle_names[] = { "Color Cycling Off", "Color Cycling On" }; |
||||
|
||||
void __cdecl gamemenu_previous() |
||||
{ |
||||
void (__cdecl *v0)(); // edx
|
||||
TMenuItem *v1; // ecx
|
||||
|
||||
if ( gbMaxPlayers == 1 ) |
||||
{ |
||||
v0 = gamemenu_enable_single; |
||||
v1 = sgSingleMenu; |
||||
} |
||||
else |
||||
{ |
||||
v0 = gamemenu_enable_multi; |
||||
v1 = sgMultiMenu; |
||||
} |
||||
gmenu_call_proc(v1, v0); |
||||
PressEscKey(); |
||||
} |
||||
// 679660: using guessed type char gbMaxPlayers;
|
||||
|
||||
void __cdecl gamemenu_enable_single() |
||||
{ |
||||
bool v0; // dl
|
||||
|
||||
gmenu_enable(&sgSingleMenu[3], gbValidSaveFile); |
||||
v0 = 0; |
||||
if ( plr[myplr]._pmode != PM_DEATH && !deathflag ) |
||||
v0 = 1; |
||||
gmenu_enable(sgSingleMenu, v0); |
||||
} |
||||
|
||||
void __cdecl gamemenu_enable_multi() |
||||
{ |
||||
gmenu_enable(&sgMultiMenu[2], deathflag); |
||||
} |
||||
|
||||
void __cdecl gamemenu_off() |
||||
{ |
||||
gmenu_call_proc(0, 0); |
||||
} |
||||
|
||||
void __cdecl gamemenu_handle_previous() |
||||
{ |
||||
if ( gmenu_exception() ) |
||||
gamemenu_off(); |
||||
else |
||||
gamemenu_previous(); |
||||
} |
||||
|
||||
void __cdecl gamemenu_new_game() |
||||
{ |
||||
int i; // eax
|
||||
|
||||
for(i = 0; i < 4; i++) |
||||
{ |
||||
plr[i]._pmode = PM_QUIT; |
||||
plr[i]._pInvincible = 1; |
||||
} |
||||
|
||||
deathflag = 0; |
||||
drawpanflag = 255; |
||||
scrollrt_draw_game_screen(1); |
||||
gbRunGame = 0; |
||||
gamemenu_off(); |
||||
} |
||||
// 525650: using guessed type int gbRunGame;
|
||||
// 52571C: using guessed type int drawpanflag;
|
||||
|
||||
void __cdecl gamemenu_quit_game() |
||||
{ |
||||
gamemenu_new_game(); |
||||
gbRunGameResult = 0; |
||||
} |
||||
// 525698: using guessed type int gbRunGameResult;
|
||||
|
||||
void __cdecl gamemenu_load_game() |
||||
{ |
||||
WNDPROC saveProc; // edi
|
||||
|
||||
saveProc = SetWindowProc(DisableInputWndProc); |
||||
gamemenu_off(); |
||||
SetCursor(0); |
||||
InitDiabloMsg(10); |
||||
drawpanflag = 255; |
||||
DrawAndBlit(); |
||||
LoadGame(FALSE); |
||||
ClrDiabloMsg(); |
||||
PaletteFadeOut(8); |
||||
deathflag = 0; |
||||
drawpanflag = 255; |
||||
DrawAndBlit(); |
||||
PaletteFadeIn(8); |
||||
SetCursor(CURSOR_HAND); |
||||
interface_msg_pump(); |
||||
SetWindowProc(saveProc); |
||||
} |
||||
// 52571C: using guessed type int drawpanflag;
|
||||
|
||||
void __cdecl gamemenu_save_game() |
||||
{ |
||||
WNDPROC saveProc; // edi
|
||||
|
||||
if ( pcurs == CURSOR_HAND ) |
||||
{ |
||||
if ( plr[myplr]._pmode == PM_DEATH || deathflag ) |
||||
{ |
||||
gamemenu_off(); |
||||
} |
||||
else |
||||
{ |
||||
saveProc = SetWindowProc(DisableInputWndProc); |
||||
SetCursor(0); |
||||
gamemenu_off(); |
||||
InitDiabloMsg(11); |
||||
drawpanflag = 255; |
||||
DrawAndBlit(); |
||||
SaveGame(); |
||||
ClrDiabloMsg(); |
||||
drawpanflag = 255; |
||||
SetCursor(CURSOR_HAND); |
||||
interface_msg_pump(); |
||||
SetWindowProc(saveProc); |
||||
} |
||||
} |
||||
} |
||||
// 52571C: using guessed type int drawpanflag;
|
||||
|
||||
void __cdecl gamemenu_restart_town() |
||||
{ |
||||
NetSendCmd(1u, CMD_RETOWN); |
||||
} |
||||
|
||||
void __cdecl gamemenu_options() |
||||
{ |
||||
gamemenu_get_music(); |
||||
gamemenu_get_sound(); |
||||
gamemenu_get_gamma(); |
||||
gamemenu_get_color_cycling(); |
||||
gmenu_call_proc(sgOptionMenu, 0); |
||||
} |
||||
|
||||
void __cdecl gamemenu_get_music() |
||||
{ |
||||
gamemenu_sound_music_toggle(music_toggle_names, sgOptionMenu, sound_get_or_set_music_volume(1)); |
||||
} |
||||
|
||||
void __fastcall gamemenu_sound_music_toggle(char **names, TMenuItem *menu_item, int gamma) |
||||
{ |
||||
if ( gbSndInited ) |
||||
{ |
||||
menu_item->dwFlags |= 0xC0000000; |
||||
menu_item->pszStr = *names; |
||||
gmenu_slider_3(menu_item, 17); |
||||
gmenu_slider_1(menu_item, -1600, 0, gamma); |
||||
} |
||||
else |
||||
{ |
||||
menu_item->dwFlags &= 0x3F000000; |
||||
menu_item->pszStr = names[1]; |
||||
} |
||||
} |
||||
|
||||
void __cdecl gamemenu_get_sound() |
||||
{ |
||||
gamemenu_sound_music_toggle(sound_toggle_names, &sgOptionMenu[1], sound_get_or_set_sound_volume(1)); |
||||
} |
||||
|
||||
void __cdecl gamemenu_get_color_cycling() |
||||
{ |
||||
sgOptionMenu[3].pszStr = color_cycling_toggle_names[palette_get_colour_cycling()]; |
||||
} |
||||
|
||||
void __cdecl gamemenu_get_gamma() |
||||
{ |
||||
gmenu_slider_3(&sgOptionMenu[2], 15); |
||||
gmenu_slider_1(&sgOptionMenu[2], 30, 100, UpdateGamma(0)); |
||||
} |
||||
|
||||
void __fastcall gamemenu_music_volume(int a1) |
||||
{ |
||||
int v1; // esi
|
||||
|
||||
if ( a1 ) |
||||
{ |
||||
if ( gbMusicOn ) |
||||
{ |
||||
gbMusicOn = 0; |
||||
music_stop(); |
||||
sound_get_or_set_music_volume(-1600); |
||||
goto LABEL_11; |
||||
} |
||||
gbMusicOn = 1; |
||||
sound_get_or_set_music_volume(0); |
||||
LABEL_10: |
||||
music_start((unsigned char)leveltype); |
||||
goto LABEL_11; |
||||
} |
||||
v1 = gamemenu_slider_music_sound(sgOptionMenu); |
||||
sound_get_or_set_music_volume(v1); |
||||
if ( v1 != -1600 ) |
||||
{ |
||||
if ( gbMusicOn ) |
||||
goto LABEL_11; |
||||
gbMusicOn = 1; |
||||
goto LABEL_10; |
||||
} |
||||
if ( gbMusicOn ) |
||||
{ |
||||
gbMusicOn = 0; |
||||
music_stop(); |
||||
} |
||||
LABEL_11: |
||||
gamemenu_get_music(); |
||||
} |
||||
// 4A22D4: using guessed type char gbMusicOn;
|
||||
// 5BB1ED: using guessed type char leveltype;
|
||||
|
||||
int __fastcall gamemenu_slider_music_sound(TMenuItem *menu_item) |
||||
{ |
||||
return gmenu_slider_get(menu_item, -1600, 0); |
||||
} |
||||
|
||||
void __fastcall gamemenu_sound_volume(int a1) |
||||
{ |
||||
int v1; // ecx
|
||||
int v2; // esi
|
||||
|
||||
if ( a1 ) |
||||
{ |
||||
if ( gbSoundOn ) |
||||
{ |
||||
gbSoundOn = 0; |
||||
FreeMonsterSnd(); |
||||
v1 = -1600; |
||||
} |
||||
else |
||||
{ |
||||
gbSoundOn = 1; |
||||
v1 = 0; |
||||
} |
||||
sound_get_or_set_sound_volume(v1); |
||||
} |
||||
else |
||||
{ |
||||
v2 = gamemenu_slider_music_sound(&sgOptionMenu[1]); |
||||
sound_get_or_set_sound_volume(v2); |
||||
if ( v2 == -1600 ) |
||||
{ |
||||
if ( gbSoundOn ) |
||||
{ |
||||
gbSoundOn = 0; |
||||
FreeMonsterSnd(); |
||||
} |
||||
} |
||||
else if ( !gbSoundOn ) |
||||
{ |
||||
gbSoundOn = 1; |
||||
} |
||||
} |
||||
PlaySFX(IS_TITLEMOV); |
||||
gamemenu_get_sound(); |
||||
} |
||||
// 4A22D5: using guessed type char gbSoundOn;
|
||||
|
||||
void __fastcall gamemenu_gamma(int a1) |
||||
{ |
||||
int v1; // eax
|
||||
int v2; // eax
|
||||
|
||||
if ( a1 ) |
||||
{ |
||||
v1 = -(UpdateGamma(0) != 30); |
||||
_LOBYTE(v1) = v1 & 0xBA; |
||||
v2 = v1 + 100; |
||||
} |
||||
else |
||||
{ |
||||
v2 = gamemenu_slider_gamma(); |
||||
} |
||||
UpdateGamma(v2); |
||||
gamemenu_get_gamma(); |
||||
} |
||||
|
||||
int __cdecl gamemenu_slider_gamma() |
||||
{ |
||||
return gmenu_slider_get(&sgOptionMenu[2], 30, 100); |
||||
} |
||||
|
||||
void __cdecl gamemenu_color_cycling() |
||||
{ |
||||
palette_set_color_cycling(palette_get_colour_cycling() == 0); |
||||
sgOptionMenu[3].pszStr = color_cycling_toggle_names[palette_get_colour_cycling() & 1]; |
||||
} |
||||
@ -0,0 +1,36 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __GAMEMENU_H__ |
||||
#define __GAMEMENU_H__ |
||||
|
||||
void __cdecl gamemenu_previous(); |
||||
void __cdecl gamemenu_enable_single(); |
||||
void __cdecl gamemenu_enable_multi(); |
||||
void __cdecl gamemenu_off(); |
||||
void __cdecl gamemenu_handle_previous(); |
||||
void __cdecl gamemenu_new_game(); |
||||
void __cdecl gamemenu_quit_game(); |
||||
void __cdecl gamemenu_load_game(); // should have 1-2 args
|
||||
void __cdecl gamemenu_save_game(); // should have 1-2 args
|
||||
void __cdecl gamemenu_restart_town(); |
||||
void __cdecl gamemenu_options(); |
||||
void __cdecl gamemenu_get_music(); |
||||
void __fastcall gamemenu_sound_music_toggle(char **names, TMenuItem *menu_item, int gamma); |
||||
void __cdecl gamemenu_get_sound(); |
||||
void __cdecl gamemenu_get_color_cycling(); |
||||
void __cdecl gamemenu_get_gamma(); |
||||
void __fastcall gamemenu_music_volume(int a1); |
||||
int __fastcall gamemenu_slider_music_sound(TMenuItem *menu_item); |
||||
void __fastcall gamemenu_sound_volume(int a1); |
||||
void __fastcall gamemenu_gamma(int a1); |
||||
int __cdecl gamemenu_slider_gamma(); |
||||
void __cdecl gamemenu_color_cycling(); |
||||
|
||||
/* rdata */ |
||||
extern TMenuItem sgSingleMenu[6]; |
||||
extern TMenuItem sgMultiMenu[5]; |
||||
extern TMenuItem sgOptionMenu[6]; |
||||
extern char *music_toggle_names[]; |
||||
extern char *sound_toggle_names[]; |
||||
extern char *color_cycling_toggle_names[]; |
||||
|
||||
#endif /* __GAMEMENU_H__ */ |
||||
@ -0,0 +1,95 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __GENDUNG_H__ |
||||
#define __GENDUNG_H__ |
||||
|
||||
extern short level_frame_types[2048]; |
||||
extern int themeCount; |
||||
extern char nTransTable[2049]; |
||||
//int dword_52D204;
|
||||
extern int dMonster[MAXDUNX][MAXDUNY]; |
||||
extern char dungeon[40][40]; |
||||
extern char dObject[MAXDUNX][MAXDUNY]; |
||||
extern void *pSpeedCels; |
||||
extern int nlevel_frames; // weak
|
||||
extern char pdungeon[40][40]; |
||||
extern char dDead[MAXDUNX][MAXDUNY]; |
||||
extern short dpiece_defs_map_1[16][MAXDUNX][MAXDUNY]; |
||||
extern char dTransVal2[MAXDUNX][MAXDUNY]; |
||||
extern char TransVal; // weak
|
||||
extern int dword_5A5594; |
||||
extern char dflags[40][40]; |
||||
extern int dPiece[MAXDUNX][MAXDUNY]; |
||||
extern char dTransVal[MAXDUNX][MAXDUNY]; |
||||
extern int setloadflag_2; // weak
|
||||
extern int tile_defs[2048]; |
||||
extern void *pMegaTiles; |
||||
extern void *pLevelPieces; |
||||
extern int gnDifficulty; // idb
|
||||
extern char block_lvid[2049]; |
||||
//char byte_5B78EB;
|
||||
extern char dung_map[MAXDUNX][MAXDUNY]; |
||||
extern char nTrapTable[2049]; |
||||
extern char leveltype; // weak
|
||||
extern unsigned char currlevel; // idb
|
||||
extern char TransList[256]; |
||||
extern UCHAR nSolidTable[2049]; |
||||
extern int level_frame_count[2048]; |
||||
extern ScrollStruct ScrollInfo; |
||||
extern void *pDungeonCels; |
||||
extern int speed_cel_frame_num_from_light_index_frame_num[16][128]; |
||||
extern THEME_LOC themeLoc[MAXTHEMES]; |
||||
extern char dPlayer[MAXDUNX][MAXDUNY]; |
||||
extern int dword_5C2FF8; // weak
|
||||
extern int dword_5C2FFC; // weak
|
||||
extern int scr_pix_width; // weak
|
||||
extern int scr_pix_height; // weak
|
||||
extern char dArch[MAXDUNX][MAXDUNY]; |
||||
extern char nBlockTable[2049]; |
||||
extern void *level_special_cel; |
||||
extern char dFlags[MAXDUNX][MAXDUNY]; |
||||
extern char dItem[MAXDUNX][MAXDUNY]; |
||||
extern char setlvlnum; // weak
|
||||
extern int level_frame_sizes[2048]; |
||||
extern char nMissileTable[2049]; |
||||
extern char *pSetPiece_2; |
||||
extern char setlvltype; // weak
|
||||
extern char setlevel; // weak
|
||||
extern int LvlViewY; // weak
|
||||
extern int LvlViewX; // weak
|
||||
extern int dmaxx; // weak
|
||||
extern int dmaxy; // weak
|
||||
extern int setpc_h; // weak
|
||||
extern int setpc_w; // weak
|
||||
extern int setpc_x; // idb
|
||||
extern int ViewX; // idb
|
||||
extern int ViewY; // idb
|
||||
extern int setpc_y; // idb
|
||||
extern char dMissile[MAXDUNX][MAXDUNY]; |
||||
extern int dminx; // weak
|
||||
extern int dminy; // weak
|
||||
extern short dpiece_defs_map_2[16][MAXDUNX][MAXDUNY]; |
||||
|
||||
void __cdecl FillSolidBlockTbls(); |
||||
void __cdecl gendung_418D91(); |
||||
void __fastcall gendung_4191BF(int frames); |
||||
void __fastcall gendung_4191FB(int a1, int a2); |
||||
int __fastcall gendung_get_dpiece_num_from_coord(int x, int y); |
||||
void __cdecl gendung_4192C2(); |
||||
void __cdecl SetDungeonMicros(); |
||||
void __cdecl DRLG_InitTrans(); |
||||
void __fastcall DRLG_MRectTrans(int x1, int y1, int x2, int y2); |
||||
void __fastcall DRLG_RectTrans(int x1, int y1, int x2, int y2); |
||||
void __fastcall DRLG_CopyTrans(int sx, int sy, int dx, int dy); |
||||
void __fastcall DRLG_ListTrans(int num, unsigned char *List); |
||||
void __fastcall DRLG_AreaTrans(int num, unsigned char *List); |
||||
void __cdecl DRLG_InitSetPC(); |
||||
void __cdecl DRLG_SetPC(); |
||||
void __fastcall Make_SetPC(int x, int y, int w, int h); |
||||
bool __fastcall DRLG_WillThemeRoomFit(int floor, int x, int y, int minSize, int maxSize, int *width, int *height); |
||||
void __fastcall DRLG_CreateThemeRoom(int themeIndex); |
||||
void __fastcall DRLG_PlaceThemeRooms(int minSize, int maxSize, int floor, int freq, int rndSize); |
||||
void __cdecl DRLG_HoldThemeRooms(); |
||||
bool __fastcall SkipThemeRoom(int x, int y); |
||||
void __cdecl InitLevels(); |
||||
|
||||
#endif /* __GENDUNG_H__ */ |
||||
@ -0,0 +1,511 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
void *optbar_cel; |
||||
bool byte_634464; // weak
|
||||
void *PentSpin_cel; |
||||
TMenuItem *sgpCurrItem; |
||||
void *BigTGold_cel; |
||||
int dword_634474; // weak
|
||||
char byte_634478; // weak
|
||||
void (__cdecl *dword_63447C)(); |
||||
TMenuItem *dword_634480; // idb
|
||||
void *option_cel; |
||||
void *sgpLogo; |
||||
int dword_63448C; // weak
|
||||
#endif |
||||
|
||||
const unsigned char lfontframe[127] = |
||||
{ |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
0, 0, 0, 37, 49, 38, 0, 39, 40, 47, |
||||
42, 43, 41, 45, 52, 44, 53, 55, 36, 27, |
||||
28, 29, 30, 31, 32, 33, 34, 35, 51, 50, |
||||
0, 46, 0, 54, 0, 1, 2, 3, 4, 5, |
||||
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, |
||||
26, 42, 0, 43, 0, 0, 0, 1, 2, 3, |
||||
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, |
||||
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, |
||||
24, 25, 26, 20, 0, 21, 0 |
||||
}; |
||||
const unsigned char lfontkern[56] = |
||||
{ |
||||
18, 33, 21, 26, 28, 19, 19, 26, 25, 11, |
||||
12, 25, 19, 34, 28, 32, 20, 32, 28, 20, |
||||
28, 36, 35, 46, 33, 33, 24, 11, 23, 22, |
||||
22, 21, 22, 21, 21, 21, 32, 10, 20, 36, |
||||
31, 17, 13, 12, 13, 18, 16, 11, 20, 21, |
||||
11, 10, 12, 11, 21, 23 |
||||
}; |
||||
|
||||
void __cdecl gmenu_draw_pause() |
||||
{ |
||||
if ( currlevel ) |
||||
RedBack(); |
||||
if ( !dword_634480 ) |
||||
{ |
||||
light_table_index = 0; |
||||
gmenu_print_text(316, 336, "Pause"); |
||||
} |
||||
} |
||||
// 69BEF8: using guessed type int light_table_index;
|
||||
|
||||
void __fastcall gmenu_print_text(int x, int y, char *pszStr) |
||||
{ |
||||
char *v3; // edi
|
||||
int v4; // ebp
|
||||
int v5; // esi
|
||||
unsigned char i; // al
|
||||
unsigned char v7; // bl
|
||||
|
||||
v3 = pszStr; |
||||
v4 = y; |
||||
v5 = x; |
||||
for ( i = *pszStr; *v3; i = *v3 ) |
||||
{ |
||||
++v3; |
||||
v7 = lfontframe[fontidx[i]]; |
||||
if ( v7 ) |
||||
CelDecodeLightOnly(v5, v4, (char *)BigTGold_cel, v7, 46); |
||||
v5 += lfontkern[v7] + 2; |
||||
} |
||||
} |
||||
|
||||
void __cdecl FreeGMenu() |
||||
{ |
||||
void *v0; // ecx
|
||||
void *v1; // ecx
|
||||
void *v2; // ecx
|
||||
void *v3; // ecx
|
||||
void *v4; // ecx
|
||||
|
||||
v0 = sgpLogo; |
||||
sgpLogo = 0; |
||||
mem_free_dbg(v0); |
||||
v1 = BigTGold_cel; |
||||
BigTGold_cel = 0; |
||||
mem_free_dbg(v1); |
||||
v2 = PentSpin_cel; |
||||
PentSpin_cel = 0; |
||||
mem_free_dbg(v2); |
||||
v3 = option_cel; |
||||
option_cel = 0; |
||||
mem_free_dbg(v3); |
||||
v4 = optbar_cel; |
||||
optbar_cel = 0; |
||||
mem_free_dbg(v4); |
||||
} |
||||
|
||||
void __cdecl gmenu_init_menu() |
||||
{ |
||||
byte_634478 = 1; |
||||
dword_634480 = 0; |
||||
sgpCurrItem = 0; |
||||
dword_63447C = 0; |
||||
dword_63448C = 0; |
||||
byte_634464 = 0; |
||||
sgpLogo = LoadFileInMem("Data\\Diabsmal.CEL", 0); |
||||
BigTGold_cel = LoadFileInMem("Data\\BigTGold.CEL", 0); |
||||
PentSpin_cel = LoadFileInMem("Data\\PentSpin.CEL", 0); |
||||
option_cel = LoadFileInMem("Data\\option.CEL", 0); |
||||
optbar_cel = LoadFileInMem("Data\\optbar.CEL", 0); |
||||
} |
||||
// 634464: using guessed type char byte_634464;
|
||||
// 634478: using guessed type char byte_634478;
|
||||
// 63448C: using guessed type int dword_63448C;
|
||||
|
||||
bool __cdecl gmenu_exception() |
||||
{ |
||||
return dword_634480 != 0; |
||||
} |
||||
|
||||
void __fastcall gmenu_call_proc(TMenuItem *pItem, void (__cdecl *gmFunc)()) |
||||
{ |
||||
TMenuItem *v2; // eax
|
||||
int v3; // ecx
|
||||
void (__cdecl **v4)(); // edx
|
||||
|
||||
PauseMode = 0; |
||||
byte_634464 = 0; |
||||
v2 = pItem; |
||||
dword_63447C = gmFunc; |
||||
dword_634480 = pItem; |
||||
if ( gmFunc ) |
||||
{ |
||||
gmFunc(); |
||||
v2 = dword_634480; |
||||
} |
||||
v3 = 0; |
||||
dword_63448C = 0; |
||||
if ( v2 ) |
||||
{ |
||||
v4 = &v2->fnMenu; |
||||
while ( *v4 ) |
||||
{ |
||||
++v3; |
||||
v4 += 3; |
||||
dword_63448C = v3; |
||||
} |
||||
} |
||||
sgpCurrItem = &v2[v3 - 1]; |
||||
gmenu_up_down(1); |
||||
} |
||||
// 525740: using guessed type int PauseMode;
|
||||
// 634464: using guessed type char byte_634464;
|
||||
// 63448C: using guessed type int dword_63448C;
|
||||
|
||||
void __fastcall gmenu_up_down(int a1) |
||||
{ |
||||
TMenuItem *v1; // eax
|
||||
int v2; // edi
|
||||
|
||||
v1 = sgpCurrItem; |
||||
if ( sgpCurrItem ) |
||||
{ |
||||
byte_634464 = 0; |
||||
v2 = dword_63448C; |
||||
while ( v2 ) |
||||
{ |
||||
--v2; |
||||
if ( a1 ) |
||||
{ |
||||
++v1; |
||||
sgpCurrItem = v1; |
||||
if ( v1->fnMenu ) |
||||
goto LABEL_10; |
||||
v1 = dword_634480; |
||||
} |
||||
else |
||||
{ |
||||
if ( v1 == dword_634480 ) |
||||
v1 = &dword_634480[dword_63448C]; |
||||
--v1; |
||||
} |
||||
sgpCurrItem = v1; |
||||
LABEL_10: |
||||
if ( (v1->dwFlags & 0x80000000) != 0 ) |
||||
{ |
||||
if ( v2 ) |
||||
PlaySFX(IS_TITLEMOV); |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
// 634464: using guessed type char byte_634464;
|
||||
// 63448C: using guessed type int dword_63448C;
|
||||
|
||||
void __cdecl gmenu_draw() |
||||
{ |
||||
int v0; // edi
|
||||
TMenuItem *i; // esi
|
||||
DWORD v2; // eax
|
||||
|
||||
if ( dword_634480 ) |
||||
{ |
||||
if ( dword_63447C ) |
||||
dword_63447C(); |
||||
CelDecodeOnly(236, 262, sgpLogo, 1, 296); |
||||
v0 = 320; |
||||
for ( i = dword_634480; i->fnMenu; v0 += 45 ) |
||||
{ |
||||
gmenu_draw_menu_item(i, v0); |
||||
++i; |
||||
} |
||||
v2 = GetTickCount(); |
||||
if ( (signed int)(v2 - dword_634474) > 25 ) |
||||
{ |
||||
if ( ++byte_634478 == 9 ) |
||||
byte_634478 = 1; |
||||
dword_634474 = v2; |
||||
} |
||||
} |
||||
} |
||||
// 634474: using guessed type int dword_634474;
|
||||
// 634478: using guessed type char byte_634478;
|
||||
|
||||
void __fastcall gmenu_draw_menu_item(TMenuItem *pItem, int a2) |
||||
{ |
||||
int v2; // edi
|
||||
TMenuItem *v3; // ebx
|
||||
unsigned int v4; // eax
|
||||
unsigned int v5; // ebp
|
||||
int v6; // esi
|
||||
unsigned int v7; // ecx
|
||||
unsigned int v8; // eax
|
||||
int v9; // ecx
|
||||
unsigned int v10; // ebp
|
||||
int v11; // esi
|
||||
int v12; // eax
|
||||
int v13; // edi
|
||||
unsigned int v14; // [esp+10h] [ebp-4h]
|
||||
|
||||
v2 = a2; |
||||
v3 = pItem; |
||||
v4 = gmenu_get_lfont(pItem); |
||||
v5 = v4; |
||||
v14 = v4; |
||||
if ( v3->dwFlags & 0x40000000 ) |
||||
{ |
||||
v6 = (v4 >> 1) + 80; |
||||
CelDecodeOnly(v6, v2 - 10, optbar_cel, 1, 287); |
||||
v7 = (v3->dwFlags >> 12) & 0xFFF; |
||||
if ( v7 < 2 ) |
||||
v7 = 2; |
||||
v8 = ((v3->dwFlags & 0xFFF) << 8) / v7; |
||||
v9 = (v5 >> 1) + 82; |
||||
v10 = v8; |
||||
gmenu_clear_buffer(v9, v2 - 12, v8 + 13, 28); |
||||
CelDecodeOnly(v6 + v10 + 2, v2 - 12, option_cel, 1, 27); |
||||
v5 = v14; |
||||
} |
||||
v11 = 384 - (v5 >> 1); |
||||
v12 = -((v3->dwFlags & 0x80000000) != 0); |
||||
_LOBYTE(v12) = v12 & 0xF1; |
||||
light_table_index = v12 + 15; |
||||
gmenu_print_text(384 - (v5 >> 1), v2, v3->pszStr); |
||||
if ( v3 == sgpCurrItem ) |
||||
{ |
||||
v13 = v2 + 1; |
||||
CelDecodeOnly(v11 - 54, v13, PentSpin_cel, (unsigned char)byte_634478, 48); |
||||
CelDecodeOnly(v11 + v5 + 4, v13, PentSpin_cel, (unsigned char)byte_634478, 48); |
||||
} |
||||
} |
||||
// 634478: using guessed type char byte_634478;
|
||||
// 69BEF8: using guessed type int light_table_index;
|
||||
|
||||
void __fastcall gmenu_clear_buffer(int x, int y, int width, int height) |
||||
{ |
||||
int v4; // edi
|
||||
char *i; // esi
|
||||
|
||||
v4 = height; |
||||
for ( i = (char *)gpBuffer + screen_y_times_768[y] + x; v4; --v4 ) |
||||
{ |
||||
memset(i, 205, width); |
||||
i -= 768; |
||||
} |
||||
} |
||||
|
||||
int __fastcall gmenu_get_lfont(TMenuItem *pItem) |
||||
{ |
||||
char *v2; // eax
|
||||
int i; // edx
|
||||
unsigned char v4; // cl
|
||||
|
||||
if ( pItem->dwFlags & 0x40000000 ) |
||||
return 490; |
||||
v2 = pItem->pszStr; |
||||
for ( i = 0; ; i += lfontkern[lfontframe[fontidx[v4]]] + 2 ) |
||||
{ |
||||
v4 = *v2; |
||||
if ( !*v2 ) |
||||
break; |
||||
++v2; |
||||
} |
||||
return i - 2; |
||||
} |
||||
|
||||
int __fastcall gmenu_presskeys(int a1) |
||||
{ |
||||
int v1; // ecx
|
||||
int v2; // ecx
|
||||
|
||||
if ( !dword_634480 ) |
||||
return 0; |
||||
switch ( a1 ) |
||||
{ |
||||
case VK_RETURN: |
||||
if ( (sgpCurrItem->dwFlags & 0x80000000) != 0 ) |
||||
{ |
||||
PlaySFX(IS_TITLEMOV); |
||||
((void (__fastcall *)(signed int))sgpCurrItem->fnMenu)(1); |
||||
} |
||||
return 1; |
||||
case VK_ESCAPE: |
||||
PlaySFX(IS_TITLEMOV); |
||||
gmenu_call_proc(0, 0); |
||||
return 1; |
||||
case VK_SPACE: |
||||
return 0; |
||||
case VK_LEFT: |
||||
v2 = 0; |
||||
goto LABEL_12; |
||||
case VK_UP: |
||||
v1 = 0; |
||||
goto LABEL_10; |
||||
case VK_RIGHT: |
||||
v2 = 1; |
||||
LABEL_12: |
||||
gmenu_left_right(v2); |
||||
return 1; |
||||
case VK_DOWN: |
||||
v1 = 1; |
||||
LABEL_10: |
||||
gmenu_up_down(v1); |
||||
break; |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
void __fastcall gmenu_left_right(int a1) |
||||
{ |
||||
signed int v1; // edx
|
||||
unsigned int v2; // eax
|
||||
int v3; // eax
|
||||
|
||||
v1 = sgpCurrItem->dwFlags; |
||||
if ( sgpCurrItem->dwFlags & 0x40000000 ) |
||||
{ |
||||
v2 = sgpCurrItem->dwFlags & 0xFFF; |
||||
if ( a1 ) |
||||
{ |
||||
if ( v2 == ((v1 >> 12) & 0xFFF) ) |
||||
return; |
||||
v3 = v2 + 1; |
||||
} |
||||
else |
||||
{ |
||||
if ( !(v1 & 0xFFF) ) |
||||
return; |
||||
v3 = v2 - 1; |
||||
} |
||||
_LOWORD(v1) = v1 & 0xF000; |
||||
sgpCurrItem->dwFlags = v1; |
||||
sgpCurrItem->dwFlags |= v3; |
||||
((void (__fastcall *)(_DWORD))sgpCurrItem->fnMenu)(0); |
||||
} |
||||
} |
||||
|
||||
int __fastcall gmenu_on_mouse_move(LPARAM lParam) |
||||
{ |
||||
int v2; // edx
|
||||
int a1; // [esp+0h] [ebp-4h]
|
||||
|
||||
a1 = lParam; |
||||
if ( !byte_634464 ) |
||||
return 0; |
||||
gmenu_valid_mouse_pos(&a1); |
||||
v2 = a1 * ((sgpCurrItem->dwFlags >> 12) & 0xFFF) % 256; |
||||
a1 = a1 * ((sgpCurrItem->dwFlags >> 12) & 0xFFF) / 256; |
||||
_LOWORD(sgpCurrItem->dwFlags) &= 0xF000u; |
||||
sgpCurrItem->dwFlags |= a1; |
||||
((void (__fastcall *)(_DWORD, int))sgpCurrItem->fnMenu)(0, v2); |
||||
return 1; |
||||
} |
||||
// 41A37A: could not find valid save-restore pair for esi
|
||||
// 634464: using guessed type char byte_634464;
|
||||
|
||||
bool __fastcall gmenu_valid_mouse_pos(int *plOffset) |
||||
{ |
||||
*plOffset = 282; |
||||
if ( MouseX < 282 ) |
||||
{ |
||||
*plOffset = 0; |
||||
return 0; |
||||
} |
||||
if ( MouseX > 538 ) |
||||
{ |
||||
*plOffset = 256; |
||||
return 0; |
||||
} |
||||
*plOffset = MouseX - 282; |
||||
return 1; |
||||
} |
||||
|
||||
int __fastcall gmenu_left_mouse(int a1) |
||||
{ |
||||
int result; // eax
|
||||
unsigned int v2; // eax
|
||||
unsigned int v3; // eax
|
||||
TMenuItem *v4; // esi
|
||||
unsigned int v5; // eax
|
||||
//LPARAM v6; // ecx
|
||||
int a1a; // [esp+4h] [ebp-4h]
|
||||
|
||||
if ( a1 ) |
||||
{ |
||||
if ( !dword_634480 || MouseY >= 352 ) |
||||
return 0; |
||||
if ( MouseY - 117 >= 0 ) |
||||
{ |
||||
v2 = (MouseY - 117) / 45; |
||||
if ( v2 < dword_63448C ) |
||||
{ |
||||
v3 = v2; |
||||
v4 = &dword_634480[v3]; |
||||
if ( (v4->dwFlags & 0x80000000) != 0 ) |
||||
{ |
||||
v5 = (unsigned int)gmenu_get_lfont(&dword_634480[v3]) >> 1; |
||||
if ( MouseX >= 320 - v5 && MouseX <= v5 + 320 ) |
||||
{ |
||||
sgpCurrItem = v4; |
||||
PlaySFX(IS_TITLEMOV); |
||||
if ( v4->dwFlags & 0x40000000 ) |
||||
{ |
||||
byte_634464 = gmenu_valid_mouse_pos(&a1a); |
||||
gmenu_on_mouse_move(a1); /* v6 */ |
||||
} |
||||
else |
||||
{ |
||||
((void (__fastcall *)(signed int))sgpCurrItem->fnMenu)(1); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
result = 0; |
||||
if ( !byte_634464 ) |
||||
return result; |
||||
byte_634464 = 0; |
||||
} |
||||
return 1; |
||||
} |
||||
// 634464: using guessed type char byte_634464;
|
||||
// 63448C: using guessed type int dword_63448C;
|
||||
|
||||
void __fastcall gmenu_enable(TMenuItem *pMenuItem, bool enable) |
||||
{ |
||||
if ( enable ) |
||||
pMenuItem->dwFlags |= 0x80000000; |
||||
else |
||||
pMenuItem->dwFlags &= 0x7F000000; |
||||
} |
||||
|
||||
void __fastcall gmenu_slider_1(TMenuItem *pItem, int min, int max, int gamma) |
||||
{ |
||||
unsigned int v4; // esi
|
||||
int v5; // eax
|
||||
|
||||
v4 = pItem->dwFlags; |
||||
v5 = (pItem->dwFlags >> 12) & 0xFFF; |
||||
if ( v5 < 2 ) |
||||
v5 = 2; |
||||
_LOWORD(v4) = v4 & 0xF000; |
||||
pItem->dwFlags = v4 | (v5 * (gamma - min) + (max - min - 1) / 2) / (max - min); |
||||
} |
||||
|
||||
int __fastcall gmenu_slider_get(TMenuItem *pItem, int min, int max) |
||||
{ |
||||
int v3; // eax
|
||||
unsigned int v4; // ecx
|
||||
|
||||
v3 = (pItem->dwFlags >> 12) & 0xFFF; |
||||
v4 = pItem->dwFlags & 0xFFF; |
||||
if ( v3 < 2 ) |
||||
v3 = 2; |
||||
return min + (v4 * (max - min) + (v3 - 1) / 2) / v3; |
||||
} |
||||
|
||||
void __fastcall gmenu_slider_3(TMenuItem *pItem, int dwTicks) |
||||
{ |
||||
pItem->dwFlags ^= (pItem->dwFlags ^ (dwTicks << 12)) & 0xFFF000; |
||||
} |
||||
@ -0,0 +1,44 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __GMENU_H__ |
||||
#define __GMENU_H__ |
||||
|
||||
extern void *optbar_cel; |
||||
extern bool byte_634464; // weak
|
||||
extern void *PentSpin_cel; |
||||
extern TMenuItem *sgpCurrItem; |
||||
extern void *BigTGold_cel; |
||||
extern int dword_634474; // weak
|
||||
extern char byte_634478; // weak
|
||||
extern void (__cdecl *dword_63447C)(); |
||||
extern TMenuItem *dword_634480; // idb
|
||||
extern void *option_cel; |
||||
extern void *sgpLogo; |
||||
extern int dword_63448C; // weak
|
||||
|
||||
void __cdecl gmenu_draw_pause(); |
||||
void __fastcall gmenu_print_text(int x, int y, char *pszStr); |
||||
void __cdecl FreeGMenu(); |
||||
void __cdecl gmenu_init_menu(); |
||||
bool __cdecl gmenu_exception(); |
||||
void __fastcall gmenu_call_proc(TMenuItem *pItem, void (__cdecl *gmFunc)()); |
||||
void __fastcall gmenu_up_down(int a1); |
||||
void __cdecl gmenu_draw(); |
||||
void __fastcall gmenu_draw_menu_item(TMenuItem *pItem, int a2); |
||||
void __fastcall gmenu_clear_buffer(int x, int y, int width, int height); |
||||
int __fastcall gmenu_get_lfont(TMenuItem *pItem); |
||||
int __fastcall gmenu_presskeys(int a1); |
||||
void __fastcall gmenu_left_right(int a1); |
||||
int __fastcall gmenu_on_mouse_move(LPARAM lParam); |
||||
bool __fastcall gmenu_valid_mouse_pos(int *plOffset); |
||||
int __fastcall gmenu_left_mouse(int a1); |
||||
void __fastcall gmenu_enable(TMenuItem *pMenuItem, bool enable); |
||||
void __fastcall gmenu_slider_1(TMenuItem *pItem, int min, int max, int gamma); |
||||
int __fastcall gmenu_slider_get(TMenuItem *pItem, int min, int max); |
||||
void __fastcall gmenu_slider_3(TMenuItem *pItem, int dwTicks); |
||||
|
||||
/* rdata */ |
||||
|
||||
extern const unsigned char lfontframe[127]; |
||||
extern const unsigned char lfontkern[56]; |
||||
|
||||
#endif /* __GMENU_H__ */ |
||||
@ -0,0 +1,272 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
#ifndef NO_GLOBALS |
||||
int help_select_line; // weak
|
||||
int dword_634494; // weak
|
||||
int helpflag; |
||||
int displayinghelp[22]; /* check, does nothing? */ |
||||
int HelpTop; // weak
|
||||
#endif |
||||
|
||||
const char gszHelpText[] = |
||||
{ |
||||
"$Keyboard Shortcuts:|" |
||||
"F1: Open Help Screen|" |
||||
"Esc: Display Main Menu|" |
||||
"Tab: Display Auto-map|" |
||||
"Space: Hide all info screens|" |
||||
"S: Open Speedbook|" |
||||
"B: Open Spellbook|" |
||||
"I: Open Inventory screen|" |
||||
"C: Open Character screen|" |
||||
"Q: Open Quest log|" |
||||
"F: Reduce screen brightness|" |
||||
"G: Increase screen brightness|" |
||||
"Z: Zoom Game Screen|" |
||||
"+ / -: Zoom Automap|" |
||||
"1 - 8: Use Belt item|" |
||||
"F5, F6, F7, F8: Set hot key for skill or spell|" |
||||
"Shift + Left Click: Attack without moving|" |
||||
"|" |
||||
"$Movement:|" |
||||
"If you hold the mouse button down while moving, the character " |
||||
"will continue to move in that direction.|" |
||||
"|" |
||||
"$Combat:|" |
||||
"Holding down the shift key and then left-clicking allows the " |
||||
"character to attack without moving.|" |
||||
"|" |
||||
"$Auto-map:|" |
||||
"To access the auto-map, click the 'MAP' button on the " |
||||
"Information Bar or press 'TAB' on the keyboard. Zooming in and " |
||||
"out of the map is done with the + and - keys. Scrolling the map " |
||||
"uses the arrow keys.|" |
||||
"|" |
||||
"$Picking up Objects:|" |
||||
"Useable items that are small in size, such as potions or scrolls, " |
||||
"are automatically placed in your 'belt' located at the top of " |
||||
"the Interface bar . When an item is placed in the belt, a small " |
||||
"number appears in that box. Items may be used by either pressing " |
||||
"the corresponding number or right-clicking on the item.|" |
||||
"|" |
||||
"$Gold|" |
||||
"You can select a specific amount of gold to drop by right " |
||||
"clicking on a pile of gold in your inventory.|" |
||||
"|" |
||||
"$Skills & Spells:|" |
||||
"You can access your list of skills and spells by left-clicking on " |
||||
"the 'SPELLS' button in the interface bar. Memorized spells and " |
||||
"those available through staffs are listed here. Left-clicking on " |
||||
"the spell you wish to cast will ready the spell. A readied spell " |
||||
"may be cast by simply right-clicking in the play area.|" |
||||
"|" |
||||
"$Using the Speedbook for Spells|" |
||||
"Left-clicking on the 'readied spell' button will open the 'Speedbook' " |
||||
"which allows you to select a skill or spell for immediate use. " |
||||
"To use a readied skill or spell, simply right-click in the main play " |
||||
"area.|" |
||||
"|" |
||||
"$Setting Spell Hotkeys|" |
||||
"You can assign up to four Hot Keys for skills, spells or scrolls. " |
||||
"Start by opening the 'speedbook' as described in the section above. " |
||||
"Press the F5, F6, F7 or F8 keys after highlighting the spell you " |
||||
"wish to assign.|" |
||||
"|" |
||||
"$Spell Books|" |
||||
"Reading more than one book increases your knowledge of that " |
||||
"spell, allowing you to cast the spell more effectively.|" |
||||
"&" |
||||
}; |
||||
|
||||
void __cdecl InitHelp() |
||||
{ |
||||
helpflag = 0; |
||||
dword_634494 = 0; |
||||
displayinghelp[0] = 0; |
||||
} |
||||
// 634494: using guessed type int dword_634494;
|
||||
|
||||
void __cdecl DrawHelp() |
||||
{ |
||||
int v0; // edi
|
||||
const char *v1; // esi
|
||||
int v2; // edx
|
||||
signed int v3; // ecx
|
||||
char v4; // al
|
||||
unsigned char v5; // al
|
||||
_BYTE *i; // eax
|
||||
int v7; // eax
|
||||
signed int v8; // edx
|
||||
char v9; // cl
|
||||
unsigned char v10; // cl
|
||||
text_color color; // [esp+Ch] [ebp-8h]
|
||||
int help_line_nr; // [esp+10h] [ebp-4h]
|
||||
signed int help_line_nra; // [esp+10h] [ebp-4h]
|
||||
|
||||
DrawSTextHelp(); |
||||
DrawQTextBack(); |
||||
PrintSString(0, 2, 1u, "Diablo Help", COL_GOLD, 0); |
||||
DrawSLine(5); |
||||
v0 = help_select_line; |
||||
v1 = gszHelpText; |
||||
if ( help_select_line > 0 ) |
||||
{ |
||||
help_line_nr = help_select_line; |
||||
do |
||||
{ |
||||
v2 = 0; |
||||
v3 = 0; |
||||
while ( !*v1 ) |
||||
++v1; |
||||
if ( *v1 == '$' ) |
||||
++v1; |
||||
v4 = *v1; |
||||
if ( *v1 != '&' ) |
||||
{ |
||||
if ( v4 == ('|') ) |
||||
goto LABEL_47; |
||||
while ( v3 < 577 ) |
||||
{ |
||||
if ( !v4 ) |
||||
{ |
||||
do |
||||
++v1; |
||||
while ( !*v1 ); |
||||
} |
||||
v5 = *v1; |
||||
tempstr[v2++] = *v1++; |
||||
v3 += fontkern[fontframe[fontidx[v5]]] + 1; |
||||
v4 = *v1; |
||||
if ( *v1 == ('|') ) |
||||
{ |
||||
if ( v3 < 577 ) |
||||
goto LABEL_18; |
||||
break; |
||||
} |
||||
} |
||||
for ( i = (unsigned char *)&tempstr[v2]-1; *i != ' '; --i ) |
||||
--v1; |
||||
LABEL_18: |
||||
if ( *v1 == ('|') ) |
||||
LABEL_47: |
||||
++v1; |
||||
} |
||||
--help_line_nr; |
||||
} |
||||
while ( help_line_nr ); |
||||
} |
||||
help_line_nra = 7; |
||||
do |
||||
{ |
||||
v7 = 0; |
||||
v8 = 0; |
||||
while ( !*v1 ) |
||||
++v1; |
||||
if ( *v1 == '$' ) |
||||
{ |
||||
++v1; |
||||
_LOBYTE(color) = COL_RED; |
||||
} |
||||
else |
||||
{ |
||||
_LOBYTE(color) = COL_WHITE; |
||||
} |
||||
v9 = *v1; |
||||
if ( *v1 == '&' ) |
||||
{ |
||||
HelpTop = v0; |
||||
} |
||||
else |
||||
{ |
||||
if ( v9 == ('|') ) |
||||
goto LABEL_48; |
||||
while ( v8 < 577 ) |
||||
{ |
||||
if ( !v9 ) |
||||
{ |
||||
do |
||||
++v1; |
||||
while ( !*v1 ); |
||||
} |
||||
v10 = *v1; |
||||
tempstr[v7++] = *v1++; |
||||
v8 += fontkern[fontframe[fontidx[v10]]] + 1; |
||||
v9 = *v1; |
||||
if ( *v1 == ('|') ) |
||||
{ |
||||
if ( v8 < 577 ) |
||||
goto LABEL_39; |
||||
break; |
||||
} |
||||
} |
||||
while ( tempstr[--v7] != ' ' ) |
||||
--v1; |
||||
LABEL_39: |
||||
if ( v7 ) |
||||
{ |
||||
tempstr[v7] = 0; |
||||
DrawHelpLine(0, help_line_nra, tempstr, color); |
||||
v0 = help_select_line; |
||||
} |
||||
if ( *v1 == ('|') ) |
||||
LABEL_48: |
||||
++v1; |
||||
} |
||||
++help_line_nra; |
||||
} |
||||
while ( help_line_nra < 22 ); |
||||
PrintSString(0, 23, 1u, "Press ESC to end or the arrow keys to scroll.", COL_GOLD, 0); |
||||
} |
||||
// 634490: using guessed type int help_select_line;
|
||||
// 634960: using guessed type int HelpTop;
|
||||
|
||||
void __fastcall DrawHelpLine(int always_0, int help_line_nr, char *text, text_color color) |
||||
{ |
||||
signed int v4; // ebx
|
||||
int v5; // edi
|
||||
unsigned char i; // al
|
||||
unsigned char v7; // al
|
||||
int v8; // esi
|
||||
|
||||
v4 = 0; |
||||
v5 = screen_y_times_768[SStringY[help_line_nr] + 204] + always_0 + 96; |
||||
for ( i = *text; *text; i = *text ) |
||||
{ |
||||
++text; |
||||
v7 = fontframe[fontidx[i]]; |
||||
v8 = v7; |
||||
v4 += fontkern[v7] + 1; |
||||
if ( v7 ) |
||||
{ |
||||
if ( v4 <= 577 ) |
||||
CPrintString(v5, v7, color); |
||||
} |
||||
v5 += fontkern[v8] + 1; |
||||
} |
||||
} |
||||
|
||||
void __cdecl DisplayHelp() |
||||
{ |
||||
help_select_line = 0; |
||||
helpflag = 1; |
||||
HelpTop = 5000; |
||||
} |
||||
// 634490: using guessed type int help_select_line;
|
||||
// 634960: using guessed type int HelpTop;
|
||||
|
||||
void __cdecl HelpScrollUp() |
||||
{ |
||||
if ( help_select_line > 0 ) |
||||
--help_select_line; |
||||
} |
||||
// 634490: using guessed type int help_select_line;
|
||||
|
||||
void __cdecl HelpScrollDown() |
||||
{ |
||||
if ( help_select_line < HelpTop ) |
||||
++help_select_line; |
||||
} |
||||
// 634490: using guessed type int help_select_line;
|
||||
// 634960: using guessed type int HelpTop;
|
||||
@ -0,0 +1,21 @@
|
||||
//HEADER_GOES_HERE
|
||||
#ifndef __HELP_H__ |
||||
#define __HELP_H__ |
||||
|
||||
extern int help_select_line; // weak
|
||||
extern int dword_634494; // weak
|
||||
extern int helpflag; |
||||
extern int displayinghelp[22]; |
||||
extern int HelpTop; // weak
|
||||
|
||||
void __cdecl InitHelp(); |
||||
void __cdecl DrawHelp(); |
||||
void __fastcall DrawHelpLine(int always_0, int help_line_nr, char *text, text_color color); |
||||
void __cdecl DisplayHelp(); |
||||
void __cdecl HelpScrollUp(); |
||||
void __cdecl HelpScrollDown(); |
||||
|
||||
/* rdata */ |
||||
extern const char gszHelpText[]; |
||||
|
||||
#endif /* __HELP_H__ */ |
||||
@ -0,0 +1,530 @@
|
||||
//HEADER_GOES_HERE
|
||||
|
||||
#include "../types.h" |
||||
|
||||
_SNETVERSIONDATA fileinfo; |
||||
int init_cpp_init_value; // weak
|
||||
int gbActive; // weak
|
||||
char diablo_exe_path[260]; |
||||
void *unused_mpq; |
||||
char patch_rt_mpq_path[260]; |
||||
WNDPROC CurrentProc; |
||||
void *diabdat_mpq; |
||||
char diabdat_mpq_path[260]; |
||||
void *patch_rt_mpq; |
||||
int killed_mom_parent; // weak
|
||||
bool screensaver_enabled_prev; |
||||
|
||||
const int init_inf = 0x7F800000; // weak
|
||||
|
||||
/* data */ |
||||
|
||||
char gszVersionNumber[260] = "internal version unknown"; |
||||
char gszProductName[260] = "Diablo v1.09"; |
||||
|
||||
struct init_cpp_init |
||||
{ |
||||
init_cpp_init() |
||||
{ |
||||
init_cpp_init_value = init_inf; |
||||
} |
||||
} _init_cpp_init; |
||||
// 47AE20: using guessed type int init_inf;
|
||||
// 63497C: using guessed type int init_cpp_init_value;
|
||||
|
||||
void __fastcall init_cleanup(bool show_cursor) |
||||
{ |
||||
int v1; // edi
|
||||
|
||||
v1 = show_cursor; |
||||
pfile_flush_W(); |
||||
init_disable_screensaver(0); |
||||
init_run_office_from_start_menu(); |
||||
if ( diabdat_mpq ) |
||||
{ |
||||
SFileCloseArchive(diabdat_mpq); |
||||
diabdat_mpq = 0; |
||||
} |
||||
if ( patch_rt_mpq ) |
||||
{ |
||||
SFileCloseArchive(patch_rt_mpq); |
||||
patch_rt_mpq = 0; |
||||
} |
||||
if ( unused_mpq ) |
||||
{ |
||||
SFileCloseArchive(unused_mpq); |
||||
unused_mpq = 0; |
||||
} |
||||
UiDestroy(); |
||||
effects_cleanup_sfx(); |
||||
sound_cleanup(); |
||||
NetClose(); |
||||
dx_cleanup(); |
||||
MI_Dummy(v1); |
||||
StormDestroy(); |
||||
if ( v1 ) |
||||
ShowCursor(1); |
||||
} |
||||
|
||||
void __cdecl init_run_office_from_start_menu() |
||||
{ |
||||
HWND v0; // eax
|
||||
char pszPath[256]; // [esp+0h] [ebp-104h]
|
||||
LPITEMIDLIST ppidl; // [esp+100h] [ebp-4h]
|
||||
|
||||
if ( killed_mom_parent ) |
||||
{ |
||||
*pszPath = empty_string; |
||||
killed_mom_parent = 0; |
||||
memset(pszPath + 1, 0, sizeof(pszPath) - 1); |
||||
// *(_WORD *)&pszPath[253] = 0;
|
||||
//pszPath[255] = 0;
|
||||
ppidl = 0; |
||||
v0 = GetDesktopWindow(); |
||||
if ( !SHGetSpecialFolderLocation(v0, CSIDL_STARTMENU, &ppidl) ) |
||||
{ |
||||
SHGetPathFromIDList(ppidl, pszPath); |
||||
init_run_office(pszPath); |
||||
} |
||||
} |
||||
} |
||||
// 634CA0: using guessed type int killed_mom_parent;
|
||||
|
||||
void __fastcall init_run_office(char *dir) |
||||
{ |
||||
char *v1; // esi
|
||||
HANDLE v2; // ebx
|
||||
bool v3; // zf
|
||||
HWND v4; // eax
|
||||
char Directory[260]; // [esp+8h] [ebp-348h]
|
||||
char FileName[260]; // [esp+10Ch] [ebp-244h]
|
||||
struct _WIN32_FIND_DATAA FindFileData; // [esp+210h] [ebp-140h]
|
||||
|
||||
v1 = dir; |
||||
strcpy(FileName, dir); |
||||
if ( FileName[0] && Directory[strlen(FileName) + 259] == '\\' ) |
||||
strcat(FileName, "*"); |
||||
else |
||||
strcat(FileName, "\\*"); |
||||
v2 = FindFirstFile(FileName, &FindFileData); |
||||
if ( v2 != (HANDLE)-1 ) |
||||
{ |
||||
do |
||||
{ |
||||
if ( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) |
||||
{ |
||||
if ( strcmp(FindFileData.cFileName, ".") && strcmp(FindFileData.cFileName, "..") ) |
||||
{ |
||||
*Directory = empty_string; |
||||
memset(Directory + 1, 0, sizeof(Directory) - 1); |
||||
v3 = *v1 == 0; |
||||
// *(_WORD *)&Directory[257] = 0;
|
||||
//Directory[259] = 0;
|
||||
if ( v3 || v1[strlen(v1) - 1] != '\\' ) |
||||
sprintf(Directory, "%s\\%s\\", v1, FindFileData.cFileName); |
||||
else |
||||
sprintf(Directory, "%s%s\\", v1, FindFileData.cFileName); |
||||
init_run_office(Directory); |
||||
} |
||||
} |
||||
else if ( !_strcmpi(FindFileData.cFileName, "Microsoft Office Shortcut Bar.lnk") ) |
||||
{ |
||||
v4 = GetDesktopWindow(); |
||||
ShellExecute(v4, "open", FindFileData.cFileName, &empty_string, v1, SW_SHOWNORMAL); |
||||
} |
||||
} |
||||
while ( FindNextFile(v2, &FindFileData) ); |
||||
FindClose(v2); |
||||
} |
||||
} |
||||
|
||||
void __fastcall init_disable_screensaver(bool disable) |
||||
{ |
||||
bool v1; // al
|
||||
char Data[16]; // [esp+4h] [ebp-20h]
|
||||
DWORD Type; // [esp+14h] [ebp-10h]
|
||||
DWORD cbData; // [esp+18h] [ebp-Ch]
|
||||
HKEY phkResult; // [esp+1Ch] [ebp-8h]
|
||||
bool v6; // [esp+20h] [ebp-4h]
|
||||
|
||||
// BUGFIX: this is probably the worst possible way to do this. Alternatives: ExtEscape() with SETPOWERMANAGEMENT,
|
||||
// SystemParametersInfo() with SPI_SETSCREENSAVEACTIVE/SPI_SETPOWEROFFACTIVE/SPI_SETLOWPOWERACTIVE
|
||||
|
||||
v6 = disable; |
||||
if ( !RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_READ|KEY_WRITE, &phkResult) ) |
||||
{ |
||||
if ( v6 ) |
||||
{ |
||||
cbData = 16; |
||||
if ( !RegQueryValueEx(phkResult, "ScreenSaveActive", 0, &Type, (LPBYTE)Data, &cbData) ) |
||||
screensaver_enabled_prev = Data[0] != '0'; |
||||
v1 = 0; |
||||
} |
||||
else |
||||
{ |
||||
v1 = screensaver_enabled_prev; |
||||
} |
||||
Data[1] = 0; |
||||
Data[0] = (v1 != 0) + '0'; |
||||
RegSetValueEx(phkResult, "ScreenSaveActive", 0, REG_SZ, (const BYTE *)Data, 2u); |
||||
RegCloseKey(phkResult); |
||||
} |
||||
} |
||||
|
||||
void __fastcall init_create_window(int nCmdShow) |
||||
{ |
||||
|
||||
|
||||
int nHeight; // eax
|
||||
HWND hWnd; // esi
|
||||
WNDCLASSEXA wcex; // [esp+8h] [ebp-34h]
|
||||
int nWidth; // [esp+38h] [ebp-4h]
|
||||
|
||||
init_kill_mom_parent(); |
||||
pfile_init_save_directory(); |
||||
memset(&wcex, 0, sizeof(wcex)); |
||||
wcex.cbSize = sizeof(wcex); |
||||
wcex.style = CS_HREDRAW|CS_VREDRAW; |
||||
wcex.lpfnWndProc = WindowProc; |
||||
wcex.hInstance = ghInst; |
||||
wcex.hIcon = LoadIcon(ghInst, MAKEINTRESOURCE(IDI_ICON1)); |
||||
wcex.hCursor = LoadCursor(0, IDC_ARROW); |
||||
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); |
||||
wcex.lpszMenuName = "DIABLO"; |
||||
wcex.lpszClassName = "DIABLO"; |
||||
wcex.hIconSm = (HICON)LoadImage(ghInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); |
||||
if ( !RegisterClassEx(&wcex) ) |
||||
TermMsg("Unable to register window class"); |
||||
if ( GetSystemMetrics(SM_CXSCREEN) >= 640 ) |
||||
nWidth = GetSystemMetrics(SM_CXSCREEN); |
||||
else |
||||
nWidth = 640; |
||||
if ( GetSystemMetrics(SM_CYSCREEN) >= 480 ) |
||||
nHeight = GetSystemMetrics(SM_CYSCREEN); |
||||
else |
||||
nHeight = 480; |
||||
hWnd = CreateWindowEx(0, "DIABLO", "DIABLO", WS_POPUP, 0, 0, nWidth, nHeight, NULL, NULL, ghInst, NULL); |
||||
if ( !hWnd ) |
||||
TermMsg("Unable to create main window"); |
||||
ShowWindow(hWnd, SW_SHOWNORMAL); // nCmdShow used only in beta: ShowWindow(hWnd, nCmdShow)
|
||||
UpdateWindow(hWnd); |
||||
init_await_mom_parent_exit(); |
||||
dx_init(hWnd); |
||||
BlackPalette(); |
||||
snd_init(hWnd); |
||||
init_archives(); |
||||
init_disable_screensaver(1); |
||||
} |
||||
|
||||
void __cdecl init_kill_mom_parent() |
||||
{ |
||||
HWND v0; // eax
|
||||
|
||||
v0 = init_find_mom_parent(); |
||||
if ( v0 ) |
||||
{ |
||||
PostMessage(v0, WM_CLOSE, 0, 0); |
||||
killed_mom_parent = 1; |
||||
} |
||||
} |
||||
// 634CA0: using guessed type int killed_mom_parent;
|
||||
|
||||
HWND __cdecl init_find_mom_parent() |
||||
{ |
||||
HWND i; // eax
|
||||
HWND v1; // esi
|
||||
char ClassName[256]; // [esp+4h] [ebp-100h]
|
||||
|
||||
for ( i = GetForegroundWindow(); ; i = GetWindow(v1, GW_HWNDNEXT) ) |
||||
{ |
||||
v1 = i; |
||||
if ( !i ) |
||||
break; |
||||
GetClassName(i, ClassName, 255); |
||||
if ( !_strcmpi(ClassName, "MOM Parent") ) |
||||
break; |
||||
} |
||||
return v1; |
||||
} |
||||
|
||||
void __cdecl init_await_mom_parent_exit() |
||||
{ |
||||
DWORD v0; // edi
|
||||
|
||||
v0 = GetTickCount(); |
||||
do |
||||
{ |
||||
if ( !init_find_mom_parent() ) |
||||
break; |
||||
Sleep(250); |
||||
} |
||||
while ( GetTickCount() - v0 <= 4000 ); |
||||
} |
||||
|
||||
void __cdecl init_archives() |
||||
{ |
||||
void *a1; // [esp+8h] [ebp-8h]
|
||||
#ifdef COPYPROT |
||||
int v1; // [esp+Ch] [ebp-4h]
|
||||
#endif |
||||
|
||||
fileinfo.size = 20; |
||||
fileinfo.versionstring = gszVersionNumber; |
||||
fileinfo.executablefile = diablo_exe_path; |
||||
fileinfo.originalarchivefile = diabdat_mpq_path; |
||||
fileinfo.patcharchivefile = patch_rt_mpq_path; |
||||
init_get_file_info(); |
||||
#ifdef COPYPROT |
||||
while ( 1 ) |
||||
{ |
||||
#endif |
||||
diabdat_mpq = init_test_access(diabdat_mpq_path, "\\diabdat.mpq", "DiabloCD", 1000, 1); |
||||
#ifdef COPYPROT |
||||
if ( diabdat_mpq ) |
||||
break; |
||||
UiCopyProtError((int)&v1); |
||||
if ( v1 == COPYPROT_CANCEL ) |
||||
FileErrDlg("diabdat.mpq"); |
||||
} |
||||
#endif |
||||
if ( !WOpenFile("ui_art\\title.pcx", &a1, 1) ) |
||||
FileErrDlg("Main program archive: diabdat.mpq"); |
||||
WCloseFile(a1); |
||||
patch_rt_mpq = init_test_access(patch_rt_mpq_path, "\\patch_rt.mpq", "DiabloInstall", 2000, 0); |
||||
} |
||||
|
||||
void *__fastcall init_test_access(char *mpq_path, char *mpq_name, char *reg_loc, int flags, bool on_cd) |
||||
{ |
||||
char *v5; // esi
|
||||
char *v7; // eax
|
||||
char Filename[260]; // [esp+Ch] [ebp-314h]
|
||||
char Buffer[260]; // [esp+110h] [ebp-210h]
|
||||
char v15[260]; // [esp+214h] [ebp-10Ch]
|
||||
char *mpq_namea; // [esp+318h] [ebp-8h]
|
||||
void *archive; // [esp+31Ch] [ebp-4h]
|
||||
|
||||
mpq_namea = mpq_name; |
||||
v5 = mpq_path; |
||||
if ( !GetCurrentDirectory(0x104u, Buffer) ) |
||||
TermMsg("Can't get program path"); |
||||
init_strip_trailing_slash(Buffer); |
||||
if ( !SFileSetBasePath(Buffer) ) |
||||
TermMsg("SFileSetBasePath"); |
||||
if ( !GetModuleFileName(ghInst, Filename, 0x104u) ) |
||||
TermMsg("Can't get program name"); |
||||
v7 = strrchr(Filename, '\\'); |
||||
if ( v7 ) |
||||
*v7 = 0; |
||||
init_strip_trailing_slash(Filename); |
||||
strcpy(v5, Buffer); |
||||
strcat(v5, mpq_namea); |
||||
#ifdef COPYPROT |
||||
if ( SFileOpenArchive(v5, flags, on_cd, &archive) ) |
||||
#else |
||||
if ( SFileOpenArchive(v5, flags, 0, &archive) ) |
||||
#endif |
||||
return archive; |
||||
if ( strcmp(Filename, Buffer) ) |
||||
{ |
||||
strcpy(v5, Filename); |
||||
strcat(v5, mpq_namea); |
||||
#ifdef COPYPROT |
||||
if ( SFileOpenArchive(v5, flags, on_cd, &archive) ) |
||||
#else |
||||
if ( SFileOpenArchive(v5, flags, 0, &archive) ) |
||||
#endif |
||||
return archive; |
||||
} |
||||
v15[0] = 0; |
||||
if ( reg_loc ) |
||||
{ |
||||
if ( SRegLoadString("Archives", (const char *)reg_loc, 0, v15, 260) ) |
||||
{ |
||||
init_strip_trailing_slash(v15); |
||||
strcpy(v5, v15); |
||||
strcat(v5, mpq_namea); |
||||
#ifdef COPYPROT |
||||
if ( SFileOpenArchive(v5, flags, on_cd, &archive) ) |
||||
#else |
||||
if ( SFileOpenArchive(v5, flags, 0, &archive) ) |
||||
#endif |
||||
return archive; |
||||
} |
||||
} |
||||
if ( on_cd && init_read_test_file(v15, mpq_namea, flags, &archive) ) |
||||
{ |
||||
strcpy(v5, v15); |
||||
return archive; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
char *__fastcall init_strip_trailing_slash(char *path) |
||||
{ |
||||
char *result; // eax
|
||||
|
||||
result = strrchr(path, '\\'); |
||||
if ( result ) |
||||
{ |
||||
if ( !result[1] ) |
||||
*result = 0; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
int __fastcall init_read_test_file(char *mpq_path, char *mpq_name, int flags, void **archive) |
||||
{ |
||||
char *v4; // edi
|
||||
DWORD v5; // eax
|
||||
const char *v7; // ebx
|
||||
const char *v8; // esi
|
||||
char Buffer[260]; // [esp+Ch] [ebp-108h]
|
||||
char *mpq_patha; // [esp+110h] [ebp-4h]
|
||||
|
||||
v4 = mpq_name; |
||||
mpq_patha = mpq_path; |
||||
v5 = GetLogicalDriveStrings(0x104u, Buffer); |
||||
if ( !v5 || v5 > 0x104 ) |
||||
return 0; |
||||
while ( *v4 == '\\' ) |
||||
++v4; |
||||
v7 = Buffer; |
||||
if ( !Buffer[0] ) |
||||
return 0; |
||||
while ( 1 ) |
||||
{ |
||||
v8 = v7; |
||||
v7 += strlen(v7) + 1; |
||||
if ( GetDriveType(v8) == DRIVE_CDROM ) |
||||
{ |
||||
strcpy(mpq_patha, v8); |
||||
strcat(mpq_patha, v4); |
||||
if ( SFileOpenArchive(mpq_patha, flags, 1, archive) ) |
||||
break; |
||||
} |
||||
if ( !*v7 ) |
||||
return 0; |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
void __cdecl init_get_file_info() |
||||
{ |
||||
int v0; // eax
|
||||
DWORD v1; // edi
|
||||
void *v2; // ebx
|
||||
unsigned int uBytes; // [esp+8h] [ebp-Ch]
|
||||
DWORD dwHandle; // [esp+Ch] [ebp-8h]
|
||||
VS_FIXEDFILEINFO *lpBuffer; // [esp+10h] [ebp-4h]
|
||||
|
||||
if ( GetModuleFileName(ghInst, diablo_exe_path, 0x104u) ) |
||||
{ |
||||
v0 = GetFileVersionInfoSize(diablo_exe_path, &dwHandle); |
||||
v1 = v0; |
||||
if ( v0 ) |
||||
{ |
||||
v2 = DiabloAllocPtr(v0); |
||||
if ( GetFileVersionInfo(diablo_exe_path, 0, v1, v2) ) |
||||
{ |
||||
if ( VerQueryValue(v2, "\\", (LPVOID *)&lpBuffer, &uBytes) ) |
||||
sprintf( |
||||
gszVersionNumber, |
||||
"version %d.%d.%d.%d", |
||||
lpBuffer->dwProductVersionMS >> 16, |
||||
lpBuffer->dwProductVersionMS & 0xFFFF, |
||||
lpBuffer->dwProductVersionLS >> 16, |
||||
lpBuffer->dwProductVersionLS & 0xFFFF); |
||||
} |
||||
mem_free_dbg(v2); |
||||
} |
||||
} |
||||
} |
||||
|
||||
LRESULT __stdcall MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) |
||||
{ |
||||
if ( Msg > WM_ERASEBKGND ) |
||||
{ |
||||
if ( Msg == WM_ACTIVATEAPP ) |
||||
{ |
||||
init_activate_window(hWnd, wParam); |
||||
} |
||||
else |
||||
{ |
||||
if ( Msg == WM_QUERYNEWPALETTE ) |
||||
{ |
||||
SDrawRealizePalette(); |
||||
return 1; |
||||
} |
||||
if ( Msg == WM_PALETTECHANGED && (HWND)wParam != hWnd ) |
||||
SDrawRealizePalette(); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
switch ( Msg ) |
||||
{ |
||||
case WM_ERASEBKGND: |
||||
return 0; |
||||
case WM_CREATE: |
||||
ghMainWnd = hWnd; |
||||
break; |
||||
case WM_DESTROY: |
||||
init_cleanup(1); |
||||
ghMainWnd = 0; |
||||
PostQuitMessage(0); |
||||
break; |
||||
case WM_PAINT: |
||||
drawpanflag = 255; |
||||
break; |
||||
case WM_CLOSE: |
||||
return 0; |
||||
} |
||||
} |
||||
return DefWindowProc(hWnd, Msg, wParam, lParam); |
||||
} |
||||
// 52571C: using guessed type int drawpanflag;
|
||||
|
||||
void __fastcall init_activate_window(HWND hWnd, bool bActive) |
||||
{ |
||||
LONG dwNewLong; // eax
|
||||
|
||||
gbActive = bActive; |
||||
UiAppActivate(bActive); |
||||
dwNewLong = GetWindowLong(hWnd, GWL_STYLE); |
||||
|
||||
if ( gbActive && fullscreen ) |
||||
dwNewLong &= ~WS_SYSMENU; |
||||
else |
||||
dwNewLong |= WS_SYSMENU; |
||||
|
||||
SetWindowLong(hWnd, GWL_STYLE, dwNewLong); |
||||
|
||||
if ( gbActive ) |
||||
{ |
||||
drawpanflag = 255; |
||||
ResetPal(); |
||||
} |
||||
} |
||||
// 484364: using guessed type int fullscreen;
|
||||
// 52571C: using guessed type int drawpanflag;
|
||||
// 634980: using guessed type int gbActive;
|
||||
|
||||
LRESULT __stdcall WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) |
||||
{ |
||||
LRESULT result; // eax
|
||||
|
||||
if ( CurrentProc ) |
||||
result = CurrentProc(hWnd, Msg, wParam, lParam); |
||||
else |
||||
result = MainWndProc(hWnd, Msg, wParam, lParam); |
||||
return result; |
||||
} |
||||
|
||||
WNDPROC __stdcall SetWindowProc(WNDPROC NewProc) |
||||
{ |
||||
WNDPROC OldProc; // eax
|
||||
|
||||
OldProc = CurrentProc; |
||||
CurrentProc = NewProc; |
||||
return OldProc; |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue