First commit
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
## 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
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# 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
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.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
|
||||
*- Backup*.rdl
|
||||
|
||||
# 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 personal settings
|
||||
.cr/personal
|
||||
|
||||
# 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/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Exclude data folder
|
||||
!data/*
|
||||
!data/debug/*
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "dependencies\\MemoryModule"]
|
||||
path = dependencies\\MemoryModule
|
||||
url = https://github.com/fancycode/MemoryModule.git
|
||||
@@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to making participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces
|
||||
when an individual is representing the project or its community. Examples of
|
||||
representing a project or community include using an official project e-mail
|
||||
address, posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at hatsune@miku.cl. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
@@ -0,0 +1,3 @@
|
||||
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
||||
|
||||
Please make sure to update tests as appropriate.
|
||||
@@ -0,0 +1,25 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Project DIVA Modding 2nd Community
|
||||
Copyright (c) samyuu (nop)
|
||||
Copyright (c) ThirteenAG
|
||||
Copyright (c) Microsoft Corporation
|
||||
Copyright (c) FreeGLUT team
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.28922.388
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PD-Loader", "source\PD-Loader\PD-Loader.vcxproj", "{CA479467-D518-46A2-AC86-3098ADA99FE5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TLAC", "source\plugins\TLAC\TLAC.vcxproj", "{2B5533BB-04A1-424F-9BCA-1CA963B46B7F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Patches", "source\plugins\Patches\Patches.vcxproj", "{3FD6ACA9-E613-4FD6-BDA2-55A91C2CF65C}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Launcher", "source\plugins\Launcher\Launcher.vcxproj", "{60D5E9F4-335F-402B-9A07-D78674DFFC9B}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Render", "source\plugins\Render\Render.vcxproj", "{89F87459-768F-4638-9267-0F90CD74452D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{CA479467-D518-46A2-AC86-3098ADA99FE5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{CA479467-D518-46A2-AC86-3098ADA99FE5}.Debug|x64.Build.0 = Debug|x64
|
||||
{CA479467-D518-46A2-AC86-3098ADA99FE5}.Release|x64.ActiveCfg = Release|x64
|
||||
{CA479467-D518-46A2-AC86-3098ADA99FE5}.Release|x64.Build.0 = Release|x64
|
||||
{2B5533BB-04A1-424F-9BCA-1CA963B46B7F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2B5533BB-04A1-424F-9BCA-1CA963B46B7F}.Debug|x64.Build.0 = Debug|x64
|
||||
{2B5533BB-04A1-424F-9BCA-1CA963B46B7F}.Release|x64.ActiveCfg = Release|x64
|
||||
{2B5533BB-04A1-424F-9BCA-1CA963B46B7F}.Release|x64.Build.0 = Release|x64
|
||||
{3FD6ACA9-E613-4FD6-BDA2-55A91C2CF65C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{3FD6ACA9-E613-4FD6-BDA2-55A91C2CF65C}.Debug|x64.Build.0 = Debug|x64
|
||||
{3FD6ACA9-E613-4FD6-BDA2-55A91C2CF65C}.Release|x64.ActiveCfg = Release|x64
|
||||
{3FD6ACA9-E613-4FD6-BDA2-55A91C2CF65C}.Release|x64.Build.0 = Release|x64
|
||||
{60D5E9F4-335F-402B-9A07-D78674DFFC9B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{60D5E9F4-335F-402B-9A07-D78674DFFC9B}.Debug|x64.Build.0 = Debug|x64
|
||||
{60D5E9F4-335F-402B-9A07-D78674DFFC9B}.Release|x64.ActiveCfg = Release|x64
|
||||
{60D5E9F4-335F-402B-9A07-D78674DFFC9B}.Release|x64.Build.0 = Release|x64
|
||||
{89F87459-768F-4638-9267-0F90CD74452D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{89F87459-768F-4638-9267-0F90CD74452D}.Debug|x64.Build.0 = Debug|x64
|
||||
{89F87459-768F-4638-9267-0F90CD74452D}.Release|x64.ActiveCfg = Release|x64
|
||||
{89F87459-768F-4638-9267-0F90CD74452D}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F5AD7464-338F-4150-9DDC-85AD115BA616}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,106 @@
|
||||
# PD Loader
|
||||
|
||||
**PD Loader** lets you load plugins into **PDAFT** by placing them into a **"plugins"** folder, it includes useful ones such as input emulation and a graphical launcher.
|
||||
|
||||
## License and Legal
|
||||
|
||||
The code included in this repository is intended for the solely usage of investigative reasons for the **PDAFT** videogame.\
|
||||
Based on your current jurisdiction, it may be illegal to tamper with an arcade cabinet or its hardware and so it would be the usage of this software.\
|
||||
Protection circumvention is not provided by this software.\
|
||||
Additionally, a MIT License is provided.
|
||||
|
||||
## Installation
|
||||
|
||||
* Have a **full clean** game version **"7.10"** decompressed without any modifications.
|
||||
* Download the latest release of **PD Loader**.
|
||||
* Decompress everything into the **root folder** of the game.
|
||||
|
||||
* Install the official **"mdata"**.
|
||||
**M215** to **M270** are supported, custom ones are also supported.
|
||||
|
||||
To install them you have to drop each **"mdata"** update decompressed into the **"mdata\"** folder in the root folder of the game (create it if it doesn't exists).
|
||||
|
||||
**e.g.** For all the official **"mdata"** you should have the following folders inside:
|
||||
* M215
|
||||
* M220
|
||||
* M230
|
||||
* M240
|
||||
* M250
|
||||
* M260
|
||||
* M270
|
||||
|
||||
Files required to make **"mdata"** available in the game are included (**"ram\databank\PvList*"** files).
|
||||
|
||||
## Usage
|
||||
|
||||
**IMPORTANT:** Do *not* edit any of the *.ini* configuration files with Notepad. Use [Notepad++](https://notepad-plus-plus.org/download) (or WordPad) with UTF-8 encoding instead, otherwise your game may crash.
|
||||
|
||||
Use **"plugins\components.ini"** to enable or disable TLAC components.\
|
||||
Use **"plugins\config.ini"** to enable or disable plugins loading along other useful settings.\
|
||||
Use **"plugins\keyconfig.ini"** to change your game keybinds.\
|
||||
Use **"plugins\playerdata.ini"** to change your playername and other player customization.
|
||||
|
||||
Place any **.dva** plugin you want to use inside the **"plugins"** folder.\
|
||||
|
||||
Launch **"diva.exe"**.
|
||||
Use **"--launch"** argument to bypass the launcher and to be able to use other arguments.
|
||||
|
||||
## Screenshots
|
||||
|
||||
Your **root** game folder should look like this:
|
||||
|
||||

|
||||
|
||||
Your **"mdata"** folder should look like this:
|
||||
|
||||

|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
||||
|
||||
Please make sure to update tests as appropriate.
|
||||
|
||||
## License
|
||||
|
||||
MIT (see "LICENSE").
|
||||
|
||||
## Third party plugins
|
||||
|
||||
[DiscordDiva](https://github.com/bela333/DiscordDiva) - Discord integration by **bela333**.\
|
||||
[DivaSound](https://github.com/somewhatlurker/DivaSound) - Replacement audio output by **somewhatlurker**, this plugin is a must if you have audio issues or no audio at all.
|
||||
|
||||
## FAQ
|
||||
|
||||
Only **NVIDIA** videocards are supported for now, AMD and Intel GPU support is possible but further research needs to be done.
|
||||
|
||||
**Linux** can run the game with **Wine**, for audio you must use [DivaSound](https://github.com/somewhatlurker/DivaSound).\
|
||||
WMV movie videos are not supported and it is recommended to set **No_Movies** to **1** to prevent crashes when the game attempts to load a movie.
|
||||
|
||||
**Windows 7** is supported except for WMV movie videos.
|
||||
|
||||
Previous versions used **dinput8.dll** in the game root folder, if you still have it you must delete it.
|
||||
|
||||
Always use the original game executable.
|
||||
|
||||
Special thanks to **Brolijah**, **Skyth**, **korenkonder**, **Samyuu**, **somewhatlurker**, **Cainan**, **crash5band**, **ano**, **lybxlpsv** and everyone else who helped at the [Project DIVA Modding 2nd Community Discord](https://discord.gg/cvBVGDZ), come join us if you want to help us to improve this project.
|
||||
|
||||
## Developer FAQ
|
||||
|
||||
To enable logs and dumps create a folder called "logs" in the root folder, each dump size is 200MB so watch your disk space.
|
||||
|
||||
This is a stripdown of [**ThirteenAG's** Ultimate ASI Loader v4.47](https://github.com/ThirteenAG/Ultimate-ASI-Loader/) for **"dnsapi.dll"** usage only.
|
||||
|
||||
Solution for **Visual Studio 2019**.\
|
||||
Requires platform toolset **v142**.\
|
||||
Requires **Windows 10 SDK (10.0.17763.0)**.
|
||||
|
||||
Requires **Desktop development with C++**.\
|
||||
Requires **Windows Universal CRT SDK**.
|
||||
|
||||
Requires **.NET desktop development** (Launcher plugin).\
|
||||
Requires **.NET Framework 4 targeting pack** (Launcher plugin).\
|
||||
Requires **C++/CLI support for v142 build tools (14.21)** (Launcher plugin)
|
||||
|
||||
Requires [**Microsoft Research Detours Package**](https://github.com/microsoft/Detours) (included in the solution).\
|
||||
Requires [**FreeGLUT 3.0.0 PD**](https://github.com/Rayduxz/FreeGLUT) (included in the solution).
|
||||
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
# components.ini
|
||||
# defines which components will be enabled
|
||||
|
||||
# emulates game input through mouse and keyboard.
|
||||
# controls can be set inside the keyconfig.ini file.
|
||||
input_emulator = true
|
||||
touch_slider_emulator = true
|
||||
touch_panel_emulator = true
|
||||
|
||||
# freezes the PV select timer at 39 seconds.
|
||||
sys_timer = true
|
||||
|
||||
# loads user defined const values from the playerdata.ini config
|
||||
# and writes them to the game's PlayerData struct.
|
||||
# required for modules selection
|
||||
player_data_manager = true
|
||||
|
||||
# adjusts 2D and 3D animations to retain their original speed at different frame rates.
|
||||
# only use this component if you are running this game at higher than 60 FPS.
|
||||
frame_rate_manager = false
|
||||
|
||||
# sets an unlimited per session play count for the normal game mode.
|
||||
# this means the player won't be sent back to the title screen after 2 plays.
|
||||
stage_manager = true
|
||||
|
||||
# skip unnecessary DATA_INITIALIZE loading time, speed up SYSTEM_STARTUP and skip the startup WARNING message.
|
||||
# further improvements can be achieved by shortening the duration of the pv_999 script file as it's test loaded during the SYSTEM_STARTUP.
|
||||
fast_loader = true
|
||||
|
||||
# allows for a user controllable camera which can be toggled using F3,
|
||||
# can be controlled using W/A/S/D to move, SPACE/CTRL to ascend/descend, Q/E to rotate, R/F to zoom in/out
|
||||
# and holding SHIFT/ALT to speed up or slow down these controls.
|
||||
camera_controller = false
|
||||
|
||||
# scales the framebuffer so that it will fit the current screen or window
|
||||
# required to set resolutions in config.ini
|
||||
scale_component = true
|
||||
|
||||
# lets the user change the current game state using the F4 - F8 keys, enable the dw_gui / DATA_TESTs
|
||||
# and speed up 2D animations / menu navigation by holding SHIFT + TAB.
|
||||
# enabling this component is not recommended for most users.
|
||||
debug_component = false
|
||||
|
||||
# enables the ability to set a cap on the framerate by setting FPS.Limit in config.ini
|
||||
fps_limiter = false
|
||||
|
||||
# allows the usage of hold transfer
|
||||
target_inspector = true
|
||||
@@ -0,0 +1,55 @@
|
||||
[Global]
|
||||
# Load plugins including below options
|
||||
Enable=1
|
||||
|
||||
[Launcher]
|
||||
# Forces the launcher to be skipped, you can use the --launch parameter instead of this.
|
||||
Skip=0
|
||||
|
||||
[Patches]
|
||||
#Enable or disable mouse cursor
|
||||
Cursor=1
|
||||
#Hide Freeplay text
|
||||
Hide_Freeplay=0
|
||||
#Set the card reader and network status icons -- 0=default, 1=hidden, 2=error, 3=OK, 4=partial OK
|
||||
Status_Icons=3
|
||||
#Hide the watermark that's usually shown in PV viewing mode
|
||||
Hide_PV_Watermark=0
|
||||
#Permanently the photo controls during PV playback
|
||||
No_PV_UI=0
|
||||
#Disables showing lyrics
|
||||
No_Lyrics=0
|
||||
#Disables movies (enable this if the game hangs when loading certain PVs)
|
||||
No_Movies=0
|
||||
#Hide the volume and SE control buttons
|
||||
Hide_Volume=0
|
||||
#Disables the error banner
|
||||
No_Error=1
|
||||
|
||||
[Graphics]
|
||||
#FPS Limiter requires "fps_limiter" component to be enabled in "components.ini"
|
||||
FPS.Limit=60
|
||||
# Temporal Anti-Aliasing
|
||||
TAA=1
|
||||
# Morphological Anti-Aliasing
|
||||
MLAA=1
|
||||
|
||||
[Resolution]
|
||||
# 0 = Windowed, 1 = Borderless (Forced to desktop resolution), 2 = Fullscreen
|
||||
Display=1
|
||||
Width=1280
|
||||
Height=720
|
||||
# Fullscreen only options
|
||||
BitDepth=32
|
||||
RefreshRate=60
|
||||
|
||||
# Set a custom internal render resolution
|
||||
# HD : 1280x720
|
||||
# FHD : 1920x1080
|
||||
# WQHD : 2560x1440
|
||||
# 4K UHD: 3840x2160
|
||||
# 5K UHD: 5120x2880
|
||||
# 8K UHD: 7680x4320
|
||||
r.Enable=0
|
||||
r.Width=3840
|
||||
r.Height=2160
|
||||
@@ -0,0 +1,78 @@
|
||||
# keyconfig.ini
|
||||
# defines the input_emulator key bindings
|
||||
# multiple keys are to be specified comma separated
|
||||
|
||||
# Options:
|
||||
|
||||
# allows the user to mouse wheel scroll through the PV selection list
|
||||
mouse_scroll_pv_selection = true
|
||||
# the interval it takes for the emulated slider touch points to move from one contact point to another.
|
||||
# in most cases this does not need editing.
|
||||
touch_slider_emulation_speed = 750.0
|
||||
|
||||
# JVS Buttons:
|
||||
JVS_TEST = F1
|
||||
JVS_SERVICE = F2
|
||||
|
||||
JVS_START = Enter, Ds4_Options, XINPUT_START, MouseMiddle
|
||||
JVS_TRIANGLE = W, I, Ds4_Triangle, Ds4_DPad_Up, Ds4_L_Trigger, Ds4_R_Trigger, XINPUT_Y, XINPUT_UP, XINPUT_LT, XINPUT_RT
|
||||
JVS_SQUARE = A, J, Ds4_Square, Ds4_DPad_Left, Ds4_L_Trigger, Ds4_R_Trigger, XINPUT_X, XINPUT_LEFT, XINPUT_LT, XINPUT_RT, MouseX2
|
||||
JVS_CROSS = S, K, Ds4_Cross, Ds4_DPad_Down, Ds4_L_Trigger, Ds4_R_Trigger, XINPUT_A, XINPUT_DOWN, XINPUT_LT, XINPUT_RT, MouseX1
|
||||
JVS_CIRCLE = D, L, Ds4_Circle, Ds4_DPad_Right, Ds4_L_Trigger, Ds4_R_Trigger, XINPUT_B, XINPUT_RIGHT, XINPUT_LT, XINPUT_RT
|
||||
|
||||
JVS_LEFT = Left, Up, Ds4_L1, Ds4_L_Stick_Up, Ds4_R_Stick_Up, XINPUT_LS
|
||||
JVS_RIGHT = Right, Down, Ds4_R1, Ds4_L_Stick_Down, Ds4_R_Stick_Down, XINPUT_RS
|
||||
|
||||
# Touch Slider:
|
||||
LEFT_SIDE_SLIDE_LEFT = Q, Ds4_L_Stick_Left, XINPUT_LLEFT
|
||||
LEFT_SIDE_SLIDE_RIGHT = E, Ds4_L_Stick_Right, XINPUT_LRIGHT
|
||||
|
||||
RIGHT_SIDE_SLIDE_LEFT = U, Ds4_R_Stick_Left, XINPUT_RLEFT
|
||||
RIGHT_SIDE_SLIDE_RIGHT = O, Ds4_R_Stick_Right, XINPUT_RRIGHT
|
||||
|
||||
# --- KEYBOARD KEY NAMES: ---
|
||||
|
||||
# - Standard Keys
|
||||
# uppercase "A" to "Z", "0" to "9"
|
||||
|
||||
# - NumPad Keys
|
||||
# "NumPad0" to "NumPad9"
|
||||
# "Plus", "Minus", "Divide", "Multiply"
|
||||
|
||||
# - Function Keys
|
||||
# "F1" to "F24"
|
||||
|
||||
# - Shift Keys
|
||||
# "LeftShift", "RightShift"
|
||||
|
||||
# - Control Keys
|
||||
# "LeftControl", "RightControl"
|
||||
|
||||
# - Arrow Keys
|
||||
# "Up", "Down", "Left", "Right"
|
||||
|
||||
# - Special Keys
|
||||
# "Enter", "Tab", "Backspace", "Insert", "Delete", "Home", "End", "PageUp", "PageDown", "Escape"
|
||||
|
||||
# --- MOUSE BUTTON NAMES: ---
|
||||
# "MouseLeft", "MouseMiddle", "MouseRight", "MouseX1", "MouseX2"
|
||||
|
||||
# --- DUALSHOCK 4 BUTTON NAMES: ---
|
||||
|
||||
# - Face Buttons
|
||||
# "Ds4_Square", "Ds4_Cross", "Ds4_Circle", "Ds4_Triangle"
|
||||
|
||||
# - Standard Buttons
|
||||
# "Ds4_Share", "Ds4_Options", "Ds4_PS", "Ds4_Touch", "Ds4_L1", "Ds4_R1"
|
||||
|
||||
# - D-Pad Directions
|
||||
# "Ds4_DPad_Up", "Ds4_DPad_Right", "Ds4_DPad_Down", "Ds4_DPad_Left"
|
||||
|
||||
# - Trigger Buttons
|
||||
# "Ds4_L_Trigger", "Ds4_R_Trigger"
|
||||
|
||||
# - Left Joystick
|
||||
# "Ds4_L_Stick_Up", "Ds4_L_Stick_Right", "Ds4_L_Stick_Down", "Ds4_L_Stick_Left", "Ds4_L3"
|
||||
|
||||
# - Right Joystick
|
||||
# "Ds4_R_Stick_Up", "Ds4_R_Stick_Right", "Ds4_R_Stick_Down", "Ds4_R_Stick_Left", "Ds4_R3"
|
||||
@@ -0,0 +1,33 @@
|
||||
# playerdata.ini
|
||||
# defines constant values to be loaded into the PlayerData struct
|
||||
# this file has to be encoded using utf-8
|
||||
|
||||
player_name = NO-NAME
|
||||
level_name = 忘れないでね私の声を
|
||||
|
||||
# IDs defined in rom/gm_plate_tbl.farc/gm_plate_id.bin
|
||||
level_plate_id = 0
|
||||
|
||||
# IDs same as gam_skin%03d
|
||||
skin_equip = 0
|
||||
|
||||
# IDs defined in rom/gm_btn_se_tbl.farc/gm_btn_se_id.bin
|
||||
btn_se_equip = -1
|
||||
|
||||
# IDs defined in rom/gm_slide_se_tbl.farc/gm_slide_se_id.bin
|
||||
slide_se_equip = -1
|
||||
|
||||
# IDs defined in rom/gm_chainslide_se_tbl.farc/gm_chainslide_se_id.bin
|
||||
chainslide_se_equip = -1
|
||||
|
||||
# Show clear borders on Progress Bar for:
|
||||
# Great
|
||||
border_great = true
|
||||
# Excellent
|
||||
border_excellent = true
|
||||
|
||||
# Allows module selection (WARNING: It may cause lag in the main menu and other places)
|
||||
use_card = false
|
||||
|
||||
# Allows use of game mode modifiers (hi-speed, hidden, and sudden)
|
||||
gamemode_options = true
|
||||
@@ -0,0 +1 @@
|
||||
7%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C10%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C16%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C20%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C23%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C27%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C30%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-01%252C2029-01-01%2C41%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-01-27%252C2029-01-01%2C42%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-02-23%252C2029-01-01%2C44%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-08-04%252C2029-01-01%2C46%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-03-27%252C2029-01-01%2C48%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-02-01%252C2029-01-01%2C49%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-02-01%252C2029-01-01%2C51%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-08-04%252C2029-01-01%2C52%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-03-27%252C2029-01-01%2C55%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-06-23%252C2029-01-01%2C57%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-02-23%252C2029-01-01%2C86%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-05-15%252C2029-01-01%2C96%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-07-19%252C2029-01-01%2C204%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2010-07-16%252C2029-01-01%2C213%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2011-12-15%252C2029-01-01%2C216%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-03-19%252C2029-01-01%2C219%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-08-06%252C2029-01-01%2C220%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-12-18%252C2029-01-01%2C221%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-04-26%252C2029-01-01%2C225%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-02-05%252C2029-01-01%2C232%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-03-19%252C2029-01-01%2C249%252C1%252C0%252C2016-02-26%252C2016-04-27%252C2016-02-26%252C2029-01-01%2C251%252C1%252C0%252C2015-10-08%252C2015-11-05%252C2015-10-08%252C2029-01-01%2C253%252C1%252C0%252C2016-08-31%252C2016-10-27%252C2016-08-31%252C2029-01-01%2C254%252C1%252C0%252C2016-12-21%252C2017-12-13%252C2016-12-21%252C2029-01-01%2C255%252C1%252C0%252C2016-06-30%252C2016-08-31%252C2016-06-30%252C2029-01-01%2C257%252C1%252C0%252C2016-04-27%252C2016-06-30%252C2016-04-27%252C2029-01-01%2C259%252C1%252C0%252C2016-04-27%252C2016-06-30%252C2016-04-27%252C2029-01-01%2C260%252C1%252C0%252C2016-04-27%252C2016-06-30%252C2016-04-27%252C2029-01-01%2C261%252C1%252C0%252C2016-06-30%252C2016-08-31%252C2016-06-30%252C2029-01-01%2C262%252C1%252C0%252C2016-10-27%252C2016-12-21%252C2016-10-27%252C2029-01-01%2C263%252C1%252C0%252C2016-12-21%252C2017-12-13%252C2016-12-21%252C2029-01-01%2C265%252C1%252C0%252C2016-10-27%252C2016-12-21%252C2016-10-27%252C2029-01-01%2C266%252C1%252C0%252C2017-12-13%252C2029-01-01%252C2017-12-13%252C2029-01-01%2C267%252C1%252C0%252C2017-12-13%252C2029-01-01%252C2017-12-13%252C2029-01-01%2C402%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-02%252C2029-01-01%2C405%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2009-01-02%252C2029-01-01%2C410%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2010-06-01%252C2029-01-01%2C427%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2012-01-12%252C2029-01-01%2C600%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-11-21%252C2029-01-01%2C602%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-11-21%252C2029-01-01%2C605%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2015-04-23%252C2029-01-01%2C615%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2014-01-28%252C2029-01-01%2C616%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-11-21%252C2029-01-01%2C637%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2015-03-26%252C2029-01-01%2C638%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2013-12-17%252C2029-01-01%2C725%252C1%252C0%252C2015-11-05%252C2015-12-22%252C2015-11-05%252C2029-01-01%2C726%252C1%252C0%252C2015-11-05%252C2015-12-22%252C2015-11-05%252C2029-01-01%2C727%252C1%252C0%252C2029-01-01%252C2000-01-01%252C2015-06-26%252C2029-01-01%2C728%252C1%252C0%252C2016-01-28%252C2016-02-26%252C2016-01-28%252C2029-01-01%2C729%252C1%252C0%252C2015-10-08%252C2015-11-05%252C2015-10-08%252C2029-01-01%2C731%252C1%252C0%252C2015-12-22%252C2016-01-28%252C2015-12-22%252C2029-01-01%2C733%252C1%252C0%252C2016-01-28%252C2016-02-26%252C2016-01-28%252C2029-01-01%2C734%252C1%252C0%252C2015-11-05%252C2015-12-22%252C2015-11-05%252C2029-01-01%2C736%252C1%252C0%252C2015-10-08%252C2015-11-05%252C2015-10-08%252C2029-01-01%2C737%252C1%252C0%252C2015-12-22%252C2016-01-28%252C2015-12-22%252C2029-01-01%2C738%252C1%252C0%252C2016-01-28%252C2016-02-26%252C2016-01-28%252C2029-01-01%2C832%252C1%252C0%252C2016-08-31%252C2016-10-27%252C2016-08-31%252C2029-01-01
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
%2A%2A%$A
|
||||
+1108
File diff suppressed because it is too large
Load Diff
+27
@@ -0,0 +1,27 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Common version parameters.
|
||||
//
|
||||
// Microsoft Research Detours Package, Version 4.0.1
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
|
||||
#define _USING_V110_SDK71_ 1
|
||||
#include "winver.h"
|
||||
#if 0
|
||||
#include <windows.h>
|
||||
#include <detours.h>
|
||||
#else
|
||||
#ifndef DETOURS_STRINGIFY
|
||||
#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
|
||||
#define DETOURS_STRINGIFY_(x) #x
|
||||
#endif
|
||||
|
||||
#define VER_FILEFLAGSMASK 0x3fL
|
||||
#define VER_FILEFLAGS 0x0L
|
||||
#define VER_FILEOS 0x00040004L
|
||||
#define VER_FILETYPE 0x00000002L
|
||||
#define VER_FILESUBTYPE 0x00000000L
|
||||
#endif
|
||||
#define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS)
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Detours Test Program (syelog.h of syelog.lib)
|
||||
//
|
||||
// Microsoft Research Detours Package
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
#pragma once
|
||||
#ifndef _SYELOGD_H_
|
||||
#define _SYELOGD_H_
|
||||
#include <stdarg.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
#define SYELOG_PIPE_NAMEA "\\\\.\\pipe\\syelog"
|
||||
#define SYELOG_PIPE_NAMEW L"\\\\.\\pipe\\syelog"
|
||||
#ifdef UNICODE
|
||||
#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEW
|
||||
#else
|
||||
#define SYELOG_PIPE_NAME SYELOG_PIPE_NAMEA
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define SYELOG_MAXIMUM_MESSAGE 4086 // 4096 - sizeof(header stuff)
|
||||
|
||||
typedef struct _SYELOG_MESSAGE
|
||||
{
|
||||
USHORT nBytes;
|
||||
BYTE nFacility;
|
||||
BYTE nSeverity;
|
||||
DWORD nProcessId;
|
||||
FILETIME ftOccurance;
|
||||
BOOL fTerminate;
|
||||
CHAR szMessage[SYELOG_MAXIMUM_MESSAGE];
|
||||
} SYELOG_MESSAGE, *PSYELOG_MESSAGE;
|
||||
|
||||
|
||||
// Facility Codes.
|
||||
//
|
||||
#define SYELOG_FACILITY_KERNEL 0x10 // OS Kernel
|
||||
#define SYELOG_FACILITY_SECURITY 0x20 // OS Security
|
||||
#define SYELOG_FACILITY_LOGGING 0x30 // OS Logging-internal
|
||||
#define SYELOG_FACILITY_SERVICE 0x40 // User-mode system daemon
|
||||
#define SYELOG_FACILITY_APPLICATION 0x50 // User-mode application
|
||||
#define SYELOG_FACILITY_USER 0x60 // User self-generated.
|
||||
#define SYELOG_FACILITY_LOCAL0 0x70 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL1 0x71 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL2 0x72 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL3 0x73 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL4 0x74 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL5 0x75 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL6 0x76 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL7 0x77 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL8 0x78 // Locally defined.
|
||||
#define SYELOG_FACILITY_LOCAL9 0x79 // Locally defined.
|
||||
|
||||
// Severity Codes.
|
||||
//
|
||||
#define SYELOG_SEVERITY_FATAL 0x00 // System is dead.
|
||||
#define SYELOG_SEVERITY_ALERT 0x10 // Take action immediately.
|
||||
#define SYELOG_SEVERITY_CRITICAL 0x20 // Critical condition.
|
||||
#define SYELOG_SEVERITY_ERROR 0x30 // Error
|
||||
#define SYELOG_SEVERITY_WARNING 0x40 // Warning
|
||||
#define SYELOG_SEVERITY_NOTICE 0x50 // Significant condition.
|
||||
#define SYELOG_SEVERITY_INFORMATION 0x60 // Informational
|
||||
#define SYELOG_SEVERITY_AUDIT_FAIL 0x66 // Audit Failed
|
||||
#define SYELOG_SEVERITY_AUDIT_PASS 0x67 // Audit Succeeeded
|
||||
#define SYELOG_SEVERITY_DEBUG 0x70 // Debugging
|
||||
|
||||
// Logging Functions.
|
||||
//
|
||||
VOID SyelogOpen(PCSTR pszIdentifier, BYTE nFacility);
|
||||
VOID Syelog(BYTE nSeverity, PCSTR pszMsgf, ...);
|
||||
VOID SyelogV(BYTE nSeverity, PCSTR pszMsgf, va_list args);
|
||||
VOID SyelogClose(BOOL fTerminate);
|
||||
|
||||
#pragma warning(pop)
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif // _SYELOGD_H_
|
||||
//
|
||||
///////////////////////////////////////////////////////////////// End of File.
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
+22
@@ -0,0 +1,22 @@
|
||||
#ifndef __FREEGLUT_H__
|
||||
#define __FREEGLUT_H__
|
||||
|
||||
/*
|
||||
* freeglut.h
|
||||
*
|
||||
* The freeglut library include file
|
||||
*
|
||||
* 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
|
||||
* PAWEL W. OLSZTA 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.
|
||||
*/
|
||||
|
||||
#include "freeglut_std.h"
|
||||
#include "freeglut_ext.h"
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
#endif /* __FREEGLUT_H__ */
|
||||
+288
@@ -0,0 +1,288 @@
|
||||
#ifndef __FREEGLUT_EXT_H__
|
||||
#define __FREEGLUT_EXT_H__
|
||||
|
||||
/*
|
||||
* freeglut_ext.h
|
||||
*
|
||||
* The non-GLUT-compatible extensions to the freeglut library include file
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 2 1999
|
||||
*
|
||||
* 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
|
||||
* PAWEL W. OLSZTA 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.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Additional GLUT Key definitions for the Special key function
|
||||
*/
|
||||
#define GLUT_KEY_NUM_LOCK 0x006D
|
||||
#define GLUT_KEY_BEGIN 0x006E
|
||||
#define GLUT_KEY_DELETE 0x006F
|
||||
#define GLUT_KEY_SHIFT_L 0x0070
|
||||
#define GLUT_KEY_SHIFT_R 0x0071
|
||||
#define GLUT_KEY_CTRL_L 0x0072
|
||||
#define GLUT_KEY_CTRL_R 0x0073
|
||||
#define GLUT_KEY_ALT_L 0x0074
|
||||
#define GLUT_KEY_ALT_R 0x0075
|
||||
|
||||
/*
|
||||
* GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window
|
||||
*/
|
||||
#define GLUT_ACTION_EXIT 0
|
||||
#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1
|
||||
#define GLUT_ACTION_CONTINUE_EXECUTION 2
|
||||
|
||||
/*
|
||||
* Create a new rendering context when the user opens a new window?
|
||||
*/
|
||||
#define GLUT_CREATE_NEW_CONTEXT 0
|
||||
#define GLUT_USE_CURRENT_CONTEXT 1
|
||||
|
||||
/*
|
||||
* Direct/Indirect rendering context options (has meaning only in Unix/X11)
|
||||
*/
|
||||
#define GLUT_FORCE_INDIRECT_CONTEXT 0
|
||||
#define GLUT_ALLOW_DIRECT_CONTEXT 1
|
||||
#define GLUT_TRY_DIRECT_CONTEXT 2
|
||||
#define GLUT_FORCE_DIRECT_CONTEXT 3
|
||||
|
||||
/*
|
||||
* GLUT API Extension macro definitions -- the glutGet parameters
|
||||
*/
|
||||
#define GLUT_INIT_STATE 0x007C
|
||||
|
||||
#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9
|
||||
|
||||
#define GLUT_WINDOW_BORDER_WIDTH 0x01FA
|
||||
#define GLUT_WINDOW_BORDER_HEIGHT 0x01FB
|
||||
#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */
|
||||
|
||||
#define GLUT_VERSION 0x01FC
|
||||
|
||||
#define GLUT_RENDERING_CONTEXT 0x01FD
|
||||
#define GLUT_DIRECT_RENDERING 0x01FE
|
||||
|
||||
#define GLUT_FULL_SCREEN 0x01FF
|
||||
|
||||
#define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204
|
||||
|
||||
#define GLUT_GEOMETRY_VISUALIZE_NORMALS 0x0205
|
||||
|
||||
#define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */
|
||||
|
||||
#define GLUT_ALLOW_NEGATIVE_WINDOW_POSITION 0x0207 /* GLUT doesn't allow negative window positions by default */
|
||||
|
||||
#define GLUT_WINDOW_SRGB 0x007D
|
||||
|
||||
/*
|
||||
* New tokens for glutInitDisplayMode.
|
||||
* Only one GLUT_AUXn bit may be used at a time.
|
||||
* Value 0x0400 is defined in OpenGLUT.
|
||||
*/
|
||||
#define GLUT_AUX 0x1000
|
||||
|
||||
#define GLUT_AUX1 0x1000
|
||||
#define GLUT_AUX2 0x2000
|
||||
#define GLUT_AUX3 0x4000
|
||||
#define GLUT_AUX4 0x8000
|
||||
|
||||
/*
|
||||
* Context-related flags, see fg_state.c
|
||||
* Set the requested OpenGL version
|
||||
*/
|
||||
#define GLUT_INIT_MAJOR_VERSION 0x0200
|
||||
#define GLUT_INIT_MINOR_VERSION 0x0201
|
||||
#define GLUT_INIT_FLAGS 0x0202
|
||||
#define GLUT_INIT_PROFILE 0x0203
|
||||
|
||||
/*
|
||||
* Flags for glutInitContextFlags, see fg_init.c
|
||||
*/
|
||||
#define GLUT_DEBUG 0x0001
|
||||
#define GLUT_FORWARD_COMPATIBLE 0x0002
|
||||
|
||||
|
||||
/*
|
||||
* Flags for glutInitContextProfile, see fg_init.c
|
||||
*/
|
||||
#define GLUT_CORE_PROFILE 0x0001
|
||||
#define GLUT_COMPATIBILITY_PROFILE 0x0002
|
||||
|
||||
/*
|
||||
* GLUT API Extension macro definitions -- Spaceball button definitions
|
||||
*/
|
||||
|
||||
#define GLUT_SPACEBALL_BUTTON_A 0x0001
|
||||
#define GLUT_SPACEBALL_BUTTON_B 0x0002
|
||||
#define GLUT_SPACEBALL_BUTTON_C 0x0004
|
||||
#define GLUT_SPACEBALL_BUTTON_D 0x0008
|
||||
#define GLUT_SPACEBALL_BUTTON_E 0x0010
|
||||
|
||||
/*
|
||||
* Process loop function, see fg_main.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMainLoopEvent( void );
|
||||
FGAPI void FGAPIENTRY glutLeaveMainLoop( void );
|
||||
FGAPI void FGAPIENTRY glutExit ( void );
|
||||
|
||||
/*
|
||||
* Window management functions, see fg_window.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutFullScreenToggle( void );
|
||||
FGAPI void FGAPIENTRY glutLeaveFullScreen( void );
|
||||
|
||||
/*
|
||||
* Menu functions
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutSetMenuFont( int menuID, void* font );
|
||||
|
||||
/*
|
||||
* Window-specific callback functions, see fg_callbacks.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutPositionFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) );
|
||||
FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) );
|
||||
/* And also a destruction callback for menus */
|
||||
FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) );
|
||||
|
||||
/*
|
||||
* State setting and retrieval functions, see fg_state.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value );
|
||||
FGAPI int * FGAPIENTRY glutGetModeValues(GLenum mode, int * size);
|
||||
/* A.Donev: User-data manipulation */
|
||||
FGAPI void* FGAPIENTRY glutGetWindowData( void );
|
||||
FGAPI void FGAPIENTRY glutSetWindowData(void* data);
|
||||
FGAPI void* FGAPIENTRY glutGetMenuData( void );
|
||||
FGAPI void FGAPIENTRY glutSetMenuData(void* data);
|
||||
|
||||
/*
|
||||
* Font stuff, see fg_font.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutBitmapHeight( void* font );
|
||||
FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font );
|
||||
FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string );
|
||||
FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string );
|
||||
|
||||
/*
|
||||
* Geometry functions, see fg_geometry.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void );
|
||||
FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void );
|
||||
FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, double offset[3], double scale );
|
||||
FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, double offset[3], double scale );
|
||||
FGAPI void FGAPIENTRY glutWireCylinder( double radius, double height, GLint slices, GLint stacks);
|
||||
FGAPI void FGAPIENTRY glutSolidCylinder( double radius, double height, GLint slices, GLint stacks);
|
||||
|
||||
/*
|
||||
* Rest of functions for rendering Newell's teaset, found in fg_teapot.c
|
||||
* NB: front facing polygons have clockwise winding, not counter clockwise
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWireTeacup( double size );
|
||||
FGAPI void FGAPIENTRY glutSolidTeacup( double size );
|
||||
FGAPI void FGAPIENTRY glutWireTeaspoon( double size );
|
||||
FGAPI void FGAPIENTRY glutSolidTeaspoon( double size );
|
||||
|
||||
/*
|
||||
* Extension functions, see fg_ext.c
|
||||
*/
|
||||
typedef void (*GLUTproc)();
|
||||
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
|
||||
|
||||
/*
|
||||
* Multi-touch/multi-pointer extensions
|
||||
*/
|
||||
|
||||
#define GLUT_HAS_MULTI 1
|
||||
|
||||
/* TODO: add device_id parameter,
|
||||
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=20120518071314.GA28061%40perso.beuc.net&forum_name=freeglut-developer */
|
||||
FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) );
|
||||
|
||||
/*
|
||||
* Joystick functions, see fg_joystick.c
|
||||
*/
|
||||
/* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */
|
||||
/* If you have a serious need for these functions in your application, please either
|
||||
* contact the "freeglut" developer community at freeglut-developer@lists.sourceforge.net,
|
||||
* switch to the OpenGLUT library, or else port your joystick functionality over to PLIB's
|
||||
* "js" library.
|
||||
*/
|
||||
int glutJoystickGetNumAxes( int ident );
|
||||
int glutJoystickGetNumButtons( int ident );
|
||||
int glutJoystickNotWorking( int ident );
|
||||
float glutJoystickGetDeadBand( int ident, int axis );
|
||||
void glutJoystickSetDeadBand( int ident, int axis, float db );
|
||||
float glutJoystickGetSaturation( int ident, int axis );
|
||||
void glutJoystickSetSaturation( int ident, int axis, float st );
|
||||
void glutJoystickSetMinRange( int ident, float *axes );
|
||||
void glutJoystickSetMaxRange( int ident, float *axes );
|
||||
void glutJoystickSetCenter( int ident, float *axes );
|
||||
void glutJoystickGetMinRange( int ident, float *axes );
|
||||
void glutJoystickGetMaxRange( int ident, float *axes );
|
||||
void glutJoystickGetCenter( int ident, float *axes );
|
||||
|
||||
/*
|
||||
* Initialization functions, see fg_init.c
|
||||
*/
|
||||
/* to get the typedef for va_list */
|
||||
#include <stdarg.h>
|
||||
FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion );
|
||||
FGAPI void FGAPIENTRY glutInitContextFlags( int flags );
|
||||
FGAPI void FGAPIENTRY glutInitContextProfile( int profile );
|
||||
FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt, va_list ap ) );
|
||||
FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) );
|
||||
|
||||
/* OpenGL >= 2.0 support */
|
||||
FGAPI void FGAPIENTRY glutSetVertexAttribCoord3( GLint attrib );
|
||||
FGAPI void FGAPIENTRY glutSetVertexAttribNormal( GLint attrib );
|
||||
FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2( GLint attrib );
|
||||
|
||||
/* Mobile platforms lifecycle */
|
||||
FGAPI void FGAPIENTRY glutInitContextFunc( void (* callback)( void ) );
|
||||
FGAPI void FGAPIENTRY glutAppStatusFunc( void (* callback)( int ) );
|
||||
/* state flags that can be passed to callback set by glutAppStatusFunc */
|
||||
#define GLUT_APPSTATUS_PAUSE 0x0001
|
||||
#define GLUT_APPSTATUS_RESUME 0x0002
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the display mode definitions
|
||||
*/
|
||||
#define GLUT_CAPTIONLESS 0x0400
|
||||
#define GLUT_BORDERLESS 0x0800
|
||||
#define GLUT_SRGB 0x1000
|
||||
|
||||
/* User-argument callbacks and implementation */
|
||||
#include "freeglut_ucall.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
#endif /* __FREEGLUT_EXT_H__ */
|
||||
+654
@@ -0,0 +1,654 @@
|
||||
#ifndef __FREEGLUT_STD_H__
|
||||
#define __FREEGLUT_STD_H__
|
||||
|
||||
/*
|
||||
* freeglut_std.h
|
||||
*
|
||||
* The GLUT-compatible part of the freeglut library include file
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 2 1999
|
||||
*
|
||||
* 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
|
||||
* PAWEL W. OLSZTA 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.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Under windows, we have to differentiate between static and dynamic libraries
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
/* #pragma may not be supported by some compilers.
|
||||
* Discussion by FreeGLUT developers suggests that
|
||||
* Visual C++ specific code involving pragmas may
|
||||
* need to move to a separate header. 24th Dec 2003
|
||||
*/
|
||||
|
||||
/* Define FREEGLUT_LIB_PRAGMAS to 1 to include library
|
||||
* pragmas or to 0 to exclude library pragmas.
|
||||
* The default behavior depends on the compiler/platform.
|
||||
*/
|
||||
# ifndef FREEGLUT_LIB_PRAGMAS
|
||||
# if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE)
|
||||
# define FREEGLUT_LIB_PRAGMAS 1
|
||||
# else
|
||||
# define FREEGLUT_LIB_PRAGMAS 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# endif
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
|
||||
/* Windows static library */
|
||||
# ifdef FREEGLUT_STATIC
|
||||
|
||||
# define FGAPI
|
||||
# define FGAPIENTRY
|
||||
|
||||
/* Link with Win32 static freeglut lib */
|
||||
# if FREEGLUT_LIB_PRAGMAS
|
||||
# ifdef NDEBUG
|
||||
# pragma comment (lib, "freeglut_static.lib")
|
||||
# else
|
||||
# pragma comment (lib, "freeglut_staticd.lib")
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Windows shared library (DLL) */
|
||||
# else
|
||||
|
||||
# define FGAPIENTRY __stdcall
|
||||
# if defined(FREEGLUT_EXPORTS)
|
||||
# define FGAPI __declspec(dllexport)
|
||||
# else
|
||||
# define FGAPI __declspec(dllimport)
|
||||
|
||||
/* Link with Win32 shared freeglut lib */
|
||||
# if FREEGLUT_LIB_PRAGMAS
|
||||
# ifdef NDEBUG
|
||||
# pragma comment (lib, "freeglut.lib")
|
||||
# else
|
||||
# pragma comment (lib, "freeglutd.lib")
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
/* Drag in other Windows libraries as required by FreeGLUT */
|
||||
# if FREEGLUT_LIB_PRAGMAS
|
||||
# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */
|
||||
# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */
|
||||
# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */
|
||||
# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */
|
||||
# pragma comment (lib, "user32.lib") /* link Windows user lib */
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
/* Non-Windows definition of FGAPI and FGAPIENTRY */
|
||||
# define FGAPI
|
||||
# define FGAPIENTRY
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The freeglut and GLUT API versions
|
||||
*/
|
||||
#define FREEGLUT 1
|
||||
#define GLUT_API_VERSION 4
|
||||
#define GLUT_XLIB_IMPLEMENTATION 13
|
||||
/* Deprecated:
|
||||
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */
|
||||
#define FREEGLUT_VERSION_2_0 1
|
||||
|
||||
/*
|
||||
* Always include OpenGL and GLU headers
|
||||
*/
|
||||
/* Note: FREEGLUT_GLES is only used to cleanly bootstrap headers
|
||||
inclusion here; use GLES constants directly
|
||||
(e.g. GL_ES_VERSION_2_0) for all other needs */
|
||||
#ifdef FREEGLUT_GLES
|
||||
# include <EGL/egl.h>
|
||||
# include <GLES/gl.h>
|
||||
# include <GLES2/gl2.h>
|
||||
#elif __APPLE__
|
||||
# include <OpenGL/gl.h>
|
||||
# include <OpenGL/glu.h>
|
||||
#else
|
||||
# include <GL/gl.h>
|
||||
# include <GL/glu.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the special key codes:
|
||||
*/
|
||||
#define GLUT_KEY_F1 0x0001
|
||||
#define GLUT_KEY_F2 0x0002
|
||||
#define GLUT_KEY_F3 0x0003
|
||||
#define GLUT_KEY_F4 0x0004
|
||||
#define GLUT_KEY_F5 0x0005
|
||||
#define GLUT_KEY_F6 0x0006
|
||||
#define GLUT_KEY_F7 0x0007
|
||||
#define GLUT_KEY_F8 0x0008
|
||||
#define GLUT_KEY_F9 0x0009
|
||||
#define GLUT_KEY_F10 0x000A
|
||||
#define GLUT_KEY_F11 0x000B
|
||||
#define GLUT_KEY_F12 0x000C
|
||||
#define GLUT_KEY_LEFT 0x0064
|
||||
#define GLUT_KEY_UP 0x0065
|
||||
#define GLUT_KEY_RIGHT 0x0066
|
||||
#define GLUT_KEY_DOWN 0x0067
|
||||
#define GLUT_KEY_PAGE_UP 0x0068
|
||||
#define GLUT_KEY_PAGE_DOWN 0x0069
|
||||
#define GLUT_KEY_HOME 0x006A
|
||||
#define GLUT_KEY_END 0x006B
|
||||
#define GLUT_KEY_INSERT 0x006C
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- mouse state definitions
|
||||
*/
|
||||
#define GLUT_LEFT_BUTTON 0x0000
|
||||
#define GLUT_MIDDLE_BUTTON 0x0001
|
||||
#define GLUT_RIGHT_BUTTON 0x0002
|
||||
#define GLUT_DOWN 0x0000
|
||||
#define GLUT_UP 0x0001
|
||||
#define GLUT_LEFT 0x0000
|
||||
#define GLUT_ENTERED 0x0001
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the display mode definitions
|
||||
*/
|
||||
#define GLUT_RGB 0x0000
|
||||
#define GLUT_RGBA 0x0000
|
||||
#define GLUT_INDEX 0x0001
|
||||
#define GLUT_SINGLE 0x0000
|
||||
#define GLUT_DOUBLE 0x0002
|
||||
#define GLUT_ACCUM 0x0004
|
||||
#define GLUT_ALPHA 0x0008
|
||||
#define GLUT_DEPTH 0x0010
|
||||
#define GLUT_STENCIL 0x0020
|
||||
#define GLUT_MULTISAMPLE 0x0080
|
||||
#define GLUT_STEREO 0x0100
|
||||
#define GLUT_LUMINANCE 0x0200
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- windows and menu related definitions
|
||||
*/
|
||||
#define GLUT_MENU_NOT_IN_USE 0x0000
|
||||
#define GLUT_MENU_IN_USE 0x0001
|
||||
#define GLUT_NOT_VISIBLE 0x0000
|
||||
#define GLUT_VISIBLE 0x0001
|
||||
#define GLUT_HIDDEN 0x0000
|
||||
#define GLUT_FULLY_RETAINED 0x0001
|
||||
#define GLUT_PARTIALLY_RETAINED 0x0002
|
||||
#define GLUT_FULLY_COVERED 0x0003
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- fonts definitions
|
||||
*
|
||||
* Steve Baker suggested to make it binary compatible with GLUT:
|
||||
*/
|
||||
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__)
|
||||
# define GLUT_STROKE_ROMAN ((void *)0x0000)
|
||||
# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001)
|
||||
# define GLUT_BITMAP_9_BY_15 ((void *)0x0002)
|
||||
# define GLUT_BITMAP_8_BY_13 ((void *)0x0003)
|
||||
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004)
|
||||
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005)
|
||||
# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006)
|
||||
# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007)
|
||||
# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008)
|
||||
#else
|
||||
/*
|
||||
* I don't really know if it's a good idea... But here it goes:
|
||||
*/
|
||||
extern void* glutStrokeRoman;
|
||||
extern void* glutStrokeMonoRoman;
|
||||
extern void* glutBitmap9By15;
|
||||
extern void* glutBitmap8By13;
|
||||
extern void* glutBitmapTimesRoman10;
|
||||
extern void* glutBitmapTimesRoman24;
|
||||
extern void* glutBitmapHelvetica10;
|
||||
extern void* glutBitmapHelvetica12;
|
||||
extern void* glutBitmapHelvetica18;
|
||||
|
||||
/*
|
||||
* Those pointers will be used by following definitions:
|
||||
*/
|
||||
# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman)
|
||||
# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman)
|
||||
# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15)
|
||||
# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)
|
||||
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10)
|
||||
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24)
|
||||
# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10)
|
||||
# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12)
|
||||
# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutGet parameters
|
||||
*/
|
||||
#define GLUT_WINDOW_X 0x0064
|
||||
#define GLUT_WINDOW_Y 0x0065
|
||||
#define GLUT_WINDOW_WIDTH 0x0066
|
||||
#define GLUT_WINDOW_HEIGHT 0x0067
|
||||
#define GLUT_WINDOW_BUFFER_SIZE 0x0068
|
||||
#define GLUT_WINDOW_STENCIL_SIZE 0x0069
|
||||
#define GLUT_WINDOW_DEPTH_SIZE 0x006A
|
||||
#define GLUT_WINDOW_RED_SIZE 0x006B
|
||||
#define GLUT_WINDOW_GREEN_SIZE 0x006C
|
||||
#define GLUT_WINDOW_BLUE_SIZE 0x006D
|
||||
#define GLUT_WINDOW_ALPHA_SIZE 0x006E
|
||||
#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F
|
||||
#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070
|
||||
#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071
|
||||
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072
|
||||
#define GLUT_WINDOW_DOUBLEBUFFER 0x0073
|
||||
#define GLUT_WINDOW_RGBA 0x0074
|
||||
#define GLUT_WINDOW_PARENT 0x0075
|
||||
#define GLUT_WINDOW_NUM_CHILDREN 0x0076
|
||||
#define GLUT_WINDOW_COLORMAP_SIZE 0x0077
|
||||
#define GLUT_WINDOW_NUM_SAMPLES 0x0078
|
||||
#define GLUT_WINDOW_STEREO 0x0079
|
||||
#define GLUT_WINDOW_CURSOR 0x007A
|
||||
|
||||
#define GLUT_SCREEN_WIDTH 0x00C8
|
||||
#define GLUT_SCREEN_HEIGHT 0x00C9
|
||||
#define GLUT_SCREEN_WIDTH_MM 0x00CA
|
||||
#define GLUT_SCREEN_HEIGHT_MM 0x00CB
|
||||
#define GLUT_MENU_NUM_ITEMS 0x012C
|
||||
#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190
|
||||
#define GLUT_INIT_WINDOW_X 0x01F4
|
||||
#define GLUT_INIT_WINDOW_Y 0x01F5
|
||||
#define GLUT_INIT_WINDOW_WIDTH 0x01F6
|
||||
#define GLUT_INIT_WINDOW_HEIGHT 0x01F7
|
||||
#define GLUT_INIT_DISPLAY_MODE 0x01F8
|
||||
#define GLUT_ELAPSED_TIME 0x02BC
|
||||
#define GLUT_WINDOW_FORMAT_ID 0x007B
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutDeviceGet parameters
|
||||
*/
|
||||
#define GLUT_HAS_KEYBOARD 0x0258
|
||||
#define GLUT_HAS_MOUSE 0x0259
|
||||
#define GLUT_HAS_SPACEBALL 0x025A
|
||||
#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B
|
||||
#define GLUT_HAS_TABLET 0x025C
|
||||
#define GLUT_NUM_MOUSE_BUTTONS 0x025D
|
||||
#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E
|
||||
#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F
|
||||
#define GLUT_NUM_DIALS 0x0260
|
||||
#define GLUT_NUM_TABLET_BUTTONS 0x0261
|
||||
#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262
|
||||
#define GLUT_DEVICE_KEY_REPEAT 0x0263
|
||||
#define GLUT_HAS_JOYSTICK 0x0264
|
||||
#define GLUT_OWNS_JOYSTICK 0x0265
|
||||
#define GLUT_JOYSTICK_BUTTONS 0x0266
|
||||
#define GLUT_JOYSTICK_AXES 0x0267
|
||||
#define GLUT_JOYSTICK_POLL_RATE 0x0268
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutLayerGet parameters
|
||||
*/
|
||||
#define GLUT_OVERLAY_POSSIBLE 0x0320
|
||||
#define GLUT_LAYER_IN_USE 0x0321
|
||||
#define GLUT_HAS_OVERLAY 0x0322
|
||||
#define GLUT_TRANSPARENT_INDEX 0x0323
|
||||
#define GLUT_NORMAL_DAMAGED 0x0324
|
||||
#define GLUT_OVERLAY_DAMAGED 0x0325
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutVideoResizeGet parameters
|
||||
*/
|
||||
#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384
|
||||
#define GLUT_VIDEO_RESIZE_IN_USE 0x0385
|
||||
#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386
|
||||
#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387
|
||||
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388
|
||||
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389
|
||||
#define GLUT_VIDEO_RESIZE_X 0x038A
|
||||
#define GLUT_VIDEO_RESIZE_Y 0x038B
|
||||
#define GLUT_VIDEO_RESIZE_WIDTH 0x038C
|
||||
#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutUseLayer parameters
|
||||
*/
|
||||
#define GLUT_NORMAL 0x0000
|
||||
#define GLUT_OVERLAY 0x0001
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutGetModifiers parameters
|
||||
*/
|
||||
#define GLUT_ACTIVE_SHIFT 0x0001
|
||||
#define GLUT_ACTIVE_CTRL 0x0002
|
||||
#define GLUT_ACTIVE_ALT 0x0004
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the glutSetCursor parameters
|
||||
*/
|
||||
#define GLUT_CURSOR_RIGHT_ARROW 0x0000
|
||||
#define GLUT_CURSOR_LEFT_ARROW 0x0001
|
||||
#define GLUT_CURSOR_INFO 0x0002
|
||||
#define GLUT_CURSOR_DESTROY 0x0003
|
||||
#define GLUT_CURSOR_HELP 0x0004
|
||||
#define GLUT_CURSOR_CYCLE 0x0005
|
||||
#define GLUT_CURSOR_SPRAY 0x0006
|
||||
#define GLUT_CURSOR_WAIT 0x0007
|
||||
#define GLUT_CURSOR_TEXT 0x0008
|
||||
#define GLUT_CURSOR_CROSSHAIR 0x0009
|
||||
#define GLUT_CURSOR_UP_DOWN 0x000A
|
||||
#define GLUT_CURSOR_LEFT_RIGHT 0x000B
|
||||
#define GLUT_CURSOR_TOP_SIDE 0x000C
|
||||
#define GLUT_CURSOR_BOTTOM_SIDE 0x000D
|
||||
#define GLUT_CURSOR_LEFT_SIDE 0x000E
|
||||
#define GLUT_CURSOR_RIGHT_SIDE 0x000F
|
||||
#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010
|
||||
#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011
|
||||
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012
|
||||
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013
|
||||
#define GLUT_CURSOR_INHERIT 0x0064
|
||||
#define GLUT_CURSOR_NONE 0x0065
|
||||
#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- RGB color component specification definitions
|
||||
*/
|
||||
#define GLUT_RED 0x0000
|
||||
#define GLUT_GREEN 0x0001
|
||||
#define GLUT_BLUE 0x0002
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- additional keyboard and joystick definitions
|
||||
*/
|
||||
#define GLUT_KEY_REPEAT_OFF 0x0000
|
||||
#define GLUT_KEY_REPEAT_ON 0x0001
|
||||
#define GLUT_KEY_REPEAT_DEFAULT 0x0002
|
||||
|
||||
#define GLUT_JOYSTICK_BUTTON_A 0x0001
|
||||
#define GLUT_JOYSTICK_BUTTON_B 0x0002
|
||||
#define GLUT_JOYSTICK_BUTTON_C 0x0004
|
||||
#define GLUT_JOYSTICK_BUTTON_D 0x0008
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- game mode definitions
|
||||
*/
|
||||
#define GLUT_GAME_MODE_ACTIVE 0x0000
|
||||
#define GLUT_GAME_MODE_POSSIBLE 0x0001
|
||||
#define GLUT_GAME_MODE_WIDTH 0x0002
|
||||
#define GLUT_GAME_MODE_HEIGHT 0x0003
|
||||
#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004
|
||||
#define GLUT_GAME_MODE_REFRESH_RATE 0x0005
|
||||
#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006
|
||||
|
||||
/*
|
||||
* Initialization functions, see fglut_init.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv );
|
||||
FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y );
|
||||
FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height );
|
||||
FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode );
|
||||
FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode );
|
||||
|
||||
/*
|
||||
* Process loop function, see fg_main.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMainLoop( void );
|
||||
|
||||
/*
|
||||
* Window management functions, see fg_window.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutCreateWindow( const char* title );
|
||||
FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height );
|
||||
FGAPI void FGAPIENTRY glutDestroyWindow( int window );
|
||||
FGAPI void FGAPIENTRY glutSetWindow( int window );
|
||||
FGAPI int FGAPIENTRY glutGetWindow( void );
|
||||
FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title );
|
||||
FGAPI void FGAPIENTRY glutSetIconTitle( const char* title );
|
||||
FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height );
|
||||
FGAPI void FGAPIENTRY glutFitWindowSizeToDesktop(int width, int height);
|
||||
FGAPI void FGAPIENTRY glutPositionWindow( int x, int y );
|
||||
FGAPI void FGAPIENTRY glutShowWindow( void );
|
||||
FGAPI void FGAPIENTRY glutHideWindow( void );
|
||||
FGAPI void FGAPIENTRY glutIconifyWindow( void );
|
||||
FGAPI void FGAPIENTRY glutPushWindow( void );
|
||||
FGAPI void FGAPIENTRY glutPopWindow( void );
|
||||
FGAPI void FGAPIENTRY glutFullScreen( void );
|
||||
|
||||
/*
|
||||
* Display-related functions, see fg_display.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window );
|
||||
FGAPI void FGAPIENTRY glutPostRedisplay( void );
|
||||
FGAPI void FGAPIENTRY glutSwapBuffers( void );
|
||||
|
||||
/*
|
||||
* Mouse cursor functions, see fg_cursor.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWarpPointer( int x, int y );
|
||||
FGAPI void FGAPIENTRY glutSetCursor( int cursor );
|
||||
|
||||
/*
|
||||
* Overlay stuff, see fg_overlay.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutEstablishOverlay( void );
|
||||
FGAPI void FGAPIENTRY glutRemoveOverlay( void );
|
||||
FGAPI void FGAPIENTRY glutUseLayer( GLenum layer );
|
||||
FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void );
|
||||
FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window );
|
||||
FGAPI void FGAPIENTRY glutShowOverlay( void );
|
||||
FGAPI void FGAPIENTRY glutHideOverlay( void );
|
||||
|
||||
/*
|
||||
* Menu stuff, see fg_menu.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) );
|
||||
FGAPI void FGAPIENTRY glutDestroyMenu( int menu );
|
||||
FGAPI int FGAPIENTRY glutGetMenu( void );
|
||||
FGAPI void FGAPIENTRY glutSetMenu( int menu );
|
||||
FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value );
|
||||
FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu );
|
||||
FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value );
|
||||
FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value );
|
||||
FGAPI void FGAPIENTRY glutRemoveMenuItem( int item );
|
||||
FGAPI void FGAPIENTRY glutAttachMenu( int button );
|
||||
FGAPI void FGAPIENTRY glutDetachMenu( int button );
|
||||
|
||||
/*
|
||||
* Global callback functions, see fg_callbacks.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value );
|
||||
FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) );
|
||||
|
||||
/*
|
||||
* Window-specific callback functions, see fg_callbacks.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) );
|
||||
FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) );
|
||||
FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) );
|
||||
|
||||
FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval );
|
||||
FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) );
|
||||
FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) );
|
||||
FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) );
|
||||
|
||||
FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) );
|
||||
FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) );
|
||||
|
||||
/*
|
||||
* State setting and retrieval functions, see fg_state.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutGet( GLenum query );
|
||||
FGAPI int FGAPIENTRY glutDeviceGet( GLenum query );
|
||||
FGAPI int FGAPIENTRY glutGetModifiers( void );
|
||||
FGAPI int FGAPIENTRY glutLayerGet( GLenum query );
|
||||
|
||||
/*
|
||||
* Font stuff, see fg_font.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character );
|
||||
FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character );
|
||||
FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character );
|
||||
FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character );
|
||||
FGAPI GLfloat FGAPIENTRY glutStrokeWidthf( void* font, int character ); /* GLUT 3.8 */
|
||||
FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string );
|
||||
FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string );
|
||||
FGAPI GLfloat FGAPIENTRY glutStrokeLengthf( void* font, const unsigned char *string ); /* GLUT 3.8 */
|
||||
|
||||
/*
|
||||
* Geometry functions, see fg_geometry.c
|
||||
*/
|
||||
|
||||
FGAPI void FGAPIENTRY glutWireCube( double size );
|
||||
FGAPI void FGAPIENTRY glutSolidCube( double size );
|
||||
FGAPI void FGAPIENTRY glutWireSphere( double radius, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutSolidSphere( double radius, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutWireCone( double base, double height, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutSolidCone( double base, double height, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutWireTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
|
||||
FGAPI void FGAPIENTRY glutSolidTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
|
||||
FGAPI void FGAPIENTRY glutWireDodecahedron( void );
|
||||
FGAPI void FGAPIENTRY glutSolidDodecahedron( void );
|
||||
FGAPI void FGAPIENTRY glutWireOctahedron( void );
|
||||
FGAPI void FGAPIENTRY glutSolidOctahedron( void );
|
||||
FGAPI void FGAPIENTRY glutWireTetrahedron( void );
|
||||
FGAPI void FGAPIENTRY glutSolidTetrahedron( void );
|
||||
FGAPI void FGAPIENTRY glutWireIcosahedron( void );
|
||||
FGAPI void FGAPIENTRY glutSolidIcosahedron( void );
|
||||
|
||||
/*
|
||||
* Teapot rendering functions, found in fg_teapot.c
|
||||
* NB: front facing polygons have clockwise winding, not counter clockwise
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWireTeapot( double size );
|
||||
FGAPI void FGAPIENTRY glutSolidTeapot( double size );
|
||||
|
||||
/*
|
||||
* Game mode functions, see fg_gamemode.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutGameModeString( const char* string );
|
||||
FGAPI int FGAPIENTRY glutEnterGameMode( void );
|
||||
FGAPI void FGAPIENTRY glutLeaveGameMode( void );
|
||||
FGAPI int FGAPIENTRY glutGameModeGet( GLenum query );
|
||||
|
||||
/*
|
||||
* Video resize functions, see fg_videoresize.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query );
|
||||
FGAPI void FGAPIENTRY glutSetupVideoResizing( void );
|
||||
FGAPI void FGAPIENTRY glutStopVideoResizing( void );
|
||||
FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height );
|
||||
FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height );
|
||||
|
||||
/*
|
||||
* Colormap functions, see fg_misc.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue );
|
||||
FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component );
|
||||
FGAPI void FGAPIENTRY glutCopyColormap( int window );
|
||||
|
||||
/*
|
||||
* Misc keyboard and joystick functions, see fg_misc.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore );
|
||||
FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode );
|
||||
FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
|
||||
|
||||
/*
|
||||
* Misc functions, see fg_misc.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
|
||||
FGAPI void FGAPIENTRY glutReportErrors( void );
|
||||
|
||||
/* Comment from glut.h of classic GLUT:
|
||||
|
||||
Win32 has an annoying issue where there are multiple C run-time
|
||||
libraries (CRTs). If the executable is linked with a different CRT
|
||||
from the GLUT DLL, the GLUT DLL will not share the same CRT static
|
||||
data seen by the executable. In particular, atexit callbacks registered
|
||||
in the executable will not be called if GLUT calls its (different)
|
||||
exit routine). GLUT is typically built with the
|
||||
"/MD" option (the CRT with multithreading DLL support), but the Visual
|
||||
C++ linker default is "/ML" (the single threaded CRT).
|
||||
|
||||
One workaround to this issue is requiring users to always link with
|
||||
the same CRT as GLUT is compiled with. That requires users supply a
|
||||
non-standard option. GLUT 3.7 has its own built-in workaround where
|
||||
the executable's "exit" function pointer is covertly passed to GLUT.
|
||||
GLUT then calls the executable's exit function pointer to ensure that
|
||||
any "atexit" calls registered by the application are called if GLUT
|
||||
needs to exit.
|
||||
|
||||
Note that the __glut*WithExit routines should NEVER be called directly.
|
||||
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
|
||||
|
||||
/* to get the prototype for exit() */
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
|
||||
FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
|
||||
FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
|
||||
FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int));
|
||||
#ifndef FREEGLUT_BUILDING_LIB
|
||||
#if defined(__GNUC__)
|
||||
#define FGUNUSED __attribute__((unused))
|
||||
#else
|
||||
#define FGUNUSED
|
||||
#endif
|
||||
static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
|
||||
#define glutInit glutInit_ATEXIT_HACK
|
||||
static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
|
||||
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
|
||||
static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); }
|
||||
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
#endif /* __FREEGLUT_STD_H__ */
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
#ifndef __FREEGLUT_UCALL_H__
|
||||
#define __FREEGLUT_UCALL_H__
|
||||
|
||||
/*
|
||||
* freeglut_ucall.h
|
||||
*
|
||||
* Callbacks with user data arguments.
|
||||
*
|
||||
* 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
|
||||
* PAWEL W. OLSZTA 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.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Menu stuff, see fg_menu.c
|
||||
*/
|
||||
FGAPI int FGAPIENTRY glutCreateMenuUcall( void (* callback)( int menu, void* user_data ), void* user_data );
|
||||
|
||||
/*
|
||||
* Global callback functions, see fg_callbacks.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutTimerFuncUcall( unsigned int time, void (* callback)( int, void* ), int value, void* user_data );
|
||||
FGAPI void FGAPIENTRY glutIdleFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
|
||||
/*
|
||||
* Window-specific callback functions, see fg_callbacks.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutKeyboardFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutSpecialFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutReshapeFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutVisibilityFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutDisplayFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMouseFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutPassiveMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutEntryFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||
|
||||
FGAPI void FGAPIENTRY glutKeyboardUpFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutSpecialUpFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutJoystickFuncUcall( void (* callback)( unsigned int, int, int, int, void* ), int pollInterval, void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMenuStatusFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutOverlayDisplayFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutWindowStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||
|
||||
FGAPI void FGAPIENTRY glutSpaceballMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutSpaceballRotateFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutSpaceballButtonFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutButtonBoxFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutDialsFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutTabletMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutTabletButtonFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
|
||||
|
||||
FGAPI void FGAPIENTRY glutMouseWheelFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutPositionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutCloseFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutWMCloseFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMenuDestroyFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
|
||||
/*
|
||||
* Multi-touch/multi-pointer extensions
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMultiEntryFuncUcall( void (* callback)( int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMultiButtonFuncUcall( void (* callback)( int, int, int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMultiMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutMultiPassiveFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
|
||||
|
||||
/*
|
||||
* Initialization functions, see fg_init.c
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
FGAPI void FGAPIENTRY glutInitErrorFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
|
||||
|
||||
/* Mobile platforms lifecycle */
|
||||
FGAPI void FGAPIENTRY glutInitContextFuncUcall( void (* callback)( void* ), void* user_data );
|
||||
FGAPI void FGAPIENTRY glutAppStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
|
||||
|
||||
/*
|
||||
* Continued "hack" from GLUT applied to Ucall functions.
|
||||
* For more info, see bottom of freeglut_std.h
|
||||
*/
|
||||
|
||||
/* to get the prototype for exit() */
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
|
||||
FGAPI int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*func)(int, void*), void(__cdecl *exitfunc)(int), void* user_data);
|
||||
#ifndef FREEGLUT_BUILDING_LIB
|
||||
#if defined(__GNUC__)
|
||||
#define FGUNUSED __attribute__((unused))
|
||||
#else
|
||||
#define FGUNUSED
|
||||
#endif
|
||||
static int FGAPIENTRY FGUNUSED glutCreateMenuUcall_ATEXIT_HACK(void(*func)(int, void*), void* user_data) { return __glutCreateMenuUcallWithExit(func, exit, user_data); }
|
||||
#define glutCreateMenuUcall glutCreateMenuUcall_ATEXIT_HACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
#endif /* __FREEGLUT_UCALL_H__ */
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#ifndef __GLUT_H__
|
||||
#define __GLUT_H__
|
||||
|
||||
/*
|
||||
* glut.h
|
||||
*
|
||||
* The freeglut library include file
|
||||
*
|
||||
* 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
|
||||
* PAWEL W. OLSZTA 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.
|
||||
*/
|
||||
|
||||
#include "freeglut_std.h"
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
#endif /* __GLUT_H__ */
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,186 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
std::wstring GetModuleFileNameW(HMODULE hModule)
|
||||
{
|
||||
static constexpr auto INITIAL_BUFFER_SIZE = MAX_PATH;
|
||||
static constexpr auto MAX_ITERATIONS = 7;
|
||||
std::wstring ret;
|
||||
auto bufferSize = INITIAL_BUFFER_SIZE;
|
||||
for (size_t iterations = 0; iterations < MAX_ITERATIONS; ++iterations)
|
||||
{
|
||||
ret.resize(bufferSize);
|
||||
auto charsReturned = GetModuleFileNameW(hModule, &ret[0], bufferSize);
|
||||
if (charsReturned < ret.length())
|
||||
{
|
||||
ret.resize(charsReturned);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferSize *= 2;
|
||||
}
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
auto starts_with = [](const std::wstring& big_str, const std::wstring& small_str) -> auto
|
||||
{
|
||||
return big_str.compare(0, small_str.length(), small_str) == 0;
|
||||
};
|
||||
|
||||
// Stores a list of loaded modules with their names, WITHOUT extension
|
||||
class ModuleList
|
||||
{
|
||||
public:
|
||||
enum class SearchLocation
|
||||
{
|
||||
All,
|
||||
LocalOnly,
|
||||
SystemOnly,
|
||||
};
|
||||
|
||||
// Initializes module list
|
||||
// Needs to be called before any calls to Get or GetAll
|
||||
void Enumerate(SearchLocation location = SearchLocation::All)
|
||||
{
|
||||
constexpr size_t INITIAL_SIZE = sizeof(HMODULE) * 256;
|
||||
HMODULE* modules = static_cast<HMODULE*>(malloc(INITIAL_SIZE));
|
||||
if (modules != nullptr)
|
||||
{
|
||||
typedef BOOL(WINAPI * Func)(HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
|
||||
|
||||
HMODULE hLib = LoadLibrary(TEXT("kernel32"));
|
||||
assert(hLib != nullptr); // If this fails then everything is probably broken anyway
|
||||
|
||||
Func pEnumProcessModules = reinterpret_cast<Func>(GetProcAddress(hLib, "K32EnumProcessModules"));
|
||||
if (pEnumProcessModules == nullptr)
|
||||
{
|
||||
// Try psapi
|
||||
FreeLibrary(hLib);
|
||||
hLib = LoadLibrary(TEXT("psapi"));
|
||||
if (hLib != nullptr)
|
||||
{
|
||||
pEnumProcessModules = reinterpret_cast<Func>(GetProcAddress(hLib, "EnumProcessModules"));
|
||||
}
|
||||
}
|
||||
|
||||
if (pEnumProcessModules != nullptr)
|
||||
{
|
||||
const HANDLE currentProcess = GetCurrentProcess();
|
||||
DWORD cbNeeded = 0;
|
||||
if (pEnumProcessModules(currentProcess, modules, INITIAL_SIZE, &cbNeeded) != 0)
|
||||
{
|
||||
if (cbNeeded > INITIAL_SIZE)
|
||||
{
|
||||
HMODULE* newModules = static_cast<HMODULE*>(realloc(modules, cbNeeded));
|
||||
if (newModules != nullptr)
|
||||
{
|
||||
modules = newModules;
|
||||
|
||||
if (pEnumProcessModules(currentProcess, modules, cbNeeded, &cbNeeded) != 0)
|
||||
{
|
||||
EnumerateInternal(modules, location, cbNeeded / sizeof(HMODULE));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EnumerateInternal(modules, location, cbNeeded / sizeof(HMODULE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hLib != nullptr)
|
||||
{
|
||||
FreeLibrary(hLib);
|
||||
}
|
||||
|
||||
free(modules);
|
||||
}
|
||||
}
|
||||
|
||||
// Recreates module list
|
||||
void ReEnumerate(SearchLocation location = SearchLocation::All)
|
||||
{
|
||||
Clear();
|
||||
Enumerate(location);
|
||||
}
|
||||
|
||||
// Clears module list
|
||||
void Clear()
|
||||
{
|
||||
m_moduleList.clear();
|
||||
}
|
||||
|
||||
// Gets handle of a loaded module with given name, NULL otherwise
|
||||
HMODULE Get(const wchar_t* moduleName) const
|
||||
{
|
||||
// If vector is empty then we're trying to call it without calling Enumerate first
|
||||
assert(m_moduleList.size() != 0);
|
||||
|
||||
auto it = std::find_if(m_moduleList.begin(), m_moduleList.end(), [&](const auto& e) {
|
||||
return _wcsicmp(moduleName, std::get<1>(e).c_str()) == 0;
|
||||
});
|
||||
return it != m_moduleList.end() ? std::get<0>(*it) : nullptr;
|
||||
}
|
||||
|
||||
// Gets handles to all loaded modules with given name
|
||||
std::vector<HMODULE> GetAll(const wchar_t* moduleName) const
|
||||
{
|
||||
// If vector is empty then we're trying to call it without calling Enumerate first
|
||||
assert(m_moduleList.size() != 0);
|
||||
|
||||
std::vector<HMODULE> results;
|
||||
for (auto& e : m_moduleList)
|
||||
{
|
||||
if (_wcsicmp(moduleName, std::get<1>(e).c_str()) == 0)
|
||||
{
|
||||
results.push_back(std::get<0>(e));
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private:
|
||||
void EnumerateInternal(HMODULE* modules, SearchLocation location, size_t numModules)
|
||||
{
|
||||
const auto exeModulePath = GetModuleFileNameW(NULL).substr(0, GetModuleFileNameW(NULL).find_last_of(L"/\\"));
|
||||
|
||||
m_moduleList.reserve(numModules);
|
||||
for (size_t i = 0; i < numModules; i++)
|
||||
{
|
||||
// Obtain module name, with resizing if necessary
|
||||
auto moduleName = GetModuleFileNameW(*modules);
|
||||
|
||||
if (!moduleName.empty())
|
||||
{
|
||||
const wchar_t* nameBegin = wcsrchr(moduleName.c_str(), '\\') + 1;
|
||||
const wchar_t* dotPos = wcsrchr(nameBegin, '.');
|
||||
bool isLocal = starts_with(std::wstring(moduleName), exeModulePath);
|
||||
|
||||
if ((isLocal && location != SearchLocation::SystemOnly) || (!isLocal && location != SearchLocation::LocalOnly))
|
||||
{
|
||||
if (dotPos != nullptr)
|
||||
{
|
||||
m_moduleList.emplace_back(*modules, std::wstring(nameBegin, dotPos), isLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_moduleList.emplace_back(*modules, nameBegin, isLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modules++;
|
||||
}
|
||||
}
|
||||
|
||||
public: std::vector< std::tuple<HMODULE, std::wstring, bool> > m_moduleList;
|
||||
};
|
||||
@@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{CA479467-D518-46A2-AC86-3098ADA99FE5}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>PDLoader</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<TargetFrameworkVersion>
|
||||
</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<CLRSupport>false</CLRSupport>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>dnsapi</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>dnsapi</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>X64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>..\MemoryModule;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>x64.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;PDLOADER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\dependencies\MemoryModule;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>x64.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;PDLOADER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>x64.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;PDLOADER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\dependencies\MemoryModule;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<ModuleDefinitionFile>x64.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="exception.hpp" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="ModuleList.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="x64.def" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,38 @@
|
||||
<?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>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ModuleList.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="exception.hpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="x64.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,710 @@
|
||||
#include "framework.h"
|
||||
#include "exception.hpp"
|
||||
|
||||
HMODULE hm;
|
||||
std::vector<std::wstring> iniPaths;
|
||||
|
||||
bool iequals(std::wstring_view s1, std::wstring_view s2)
|
||||
{
|
||||
std::wstring str1(std::move(s1));
|
||||
std::wstring str2(std::move(s2));
|
||||
std::transform(str1.begin(), str1.end(), str1.begin(), [](wchar_t c) { return ::towlower(c); });
|
||||
std::transform(str2.begin(), str2.end(), str2.begin(), [](wchar_t c) { return ::towlower(c); });
|
||||
return (str1 == str2);
|
||||
}
|
||||
|
||||
std::wstring to_wstring(std::string_view cstr)
|
||||
{
|
||||
std::string str(std::move(cstr));
|
||||
auto charsReturned = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
|
||||
std::wstring wstrTo(charsReturned, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], charsReturned);
|
||||
return wstrTo;
|
||||
}
|
||||
|
||||
std::wstring SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken)
|
||||
{
|
||||
std::wstring r;
|
||||
WCHAR* szSystemPath = nullptr;
|
||||
if (SUCCEEDED(SHGetKnownFolderPath(rfid, dwFlags, hToken, &szSystemPath)))
|
||||
{
|
||||
r = szSystemPath;
|
||||
}
|
||||
CoTaskMemFree(szSystemPath);
|
||||
return r;
|
||||
};
|
||||
|
||||
HMODULE LoadLibraryW(const std::wstring& lpLibFileName)
|
||||
{
|
||||
return LoadLibraryW(lpLibFileName.c_str());
|
||||
}
|
||||
|
||||
std::wstring GetCurrentDirectoryW()
|
||||
{
|
||||
static constexpr auto INITIAL_BUFFER_SIZE = MAX_PATH;
|
||||
static constexpr auto MAX_ITERATIONS = 7;
|
||||
std::wstring ret;
|
||||
auto bufferSize = INITIAL_BUFFER_SIZE;
|
||||
for (size_t iterations = 0; iterations < MAX_ITERATIONS; ++iterations)
|
||||
{
|
||||
ret.resize(bufferSize);
|
||||
auto charsReturned = GetCurrentDirectoryW(bufferSize, &ret[0]);
|
||||
if (charsReturned < ret.length())
|
||||
{
|
||||
ret.resize(charsReturned);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufferSize *= 2;
|
||||
}
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
UINT GetPrivateProfileIntW(LPCWSTR lpAppName, LPCWSTR lpKeyName, INT nDefault, const std::vector<std::wstring>& fileNames)
|
||||
{
|
||||
for (const auto& file : fileNames)
|
||||
{
|
||||
nDefault = GetPrivateProfileIntW(lpAppName, lpKeyName, nDefault, file.c_str());
|
||||
}
|
||||
return nDefault;
|
||||
}
|
||||
|
||||
std::wstring GetSelfName()
|
||||
{
|
||||
const std::wstring moduleFileName = GetModuleFileNameW(hm);
|
||||
return moduleFileName.substr(moduleFileName.find_last_of(L"/\\") + 1);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void GetSections(T&& h, Args... args)
|
||||
{
|
||||
const std::set< std::string_view, std::less<> > s = { args... };
|
||||
size_t dwLoadOffset = (size_t)GetModuleHandle(NULL);
|
||||
BYTE* pImageBase = reinterpret_cast<BYTE*>(dwLoadOffset);
|
||||
PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(dwLoadOffset);
|
||||
PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(pImageBase + pDosHeader->e_lfanew);
|
||||
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHeader);
|
||||
for (int iSection = 0; iSection < pNtHeader->FileHeader.NumberOfSections; ++iSection, ++pSection)
|
||||
{
|
||||
auto pszSectionName = reinterpret_cast<const char*>(pSection->Name);
|
||||
if (s.find(pszSectionName) != s.end())
|
||||
{
|
||||
DWORD dwPhysSize = (pSection->Misc.VirtualSize + 4095) & ~4095;
|
||||
std::forward<T>(h)(pSection, dwLoadOffset, dwPhysSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Kernel32ExportsNames
|
||||
{
|
||||
eGetStartupInfoA,
|
||||
eGetStartupInfoW,
|
||||
eGetModuleHandleA,
|
||||
eGetModuleHandleW,
|
||||
eGetProcAddress,
|
||||
eGetShortPathNameA,
|
||||
eFindNextFileA,
|
||||
eFindNextFileW,
|
||||
eLoadLibraryA,
|
||||
eLoadLibraryW,
|
||||
eFreeLibrary,
|
||||
eCreateEventA,
|
||||
eCreateEventW,
|
||||
eGetSystemInfo,
|
||||
eInterlockedCompareExchange,
|
||||
eSleep,
|
||||
|
||||
Kernel32ExportsNamesCount
|
||||
};
|
||||
|
||||
enum Kernel32ExportsData
|
||||
{
|
||||
IATPtr,
|
||||
ProcAddress,
|
||||
|
||||
Kernel32ExportsDataCount
|
||||
};
|
||||
|
||||
size_t Kernel32Data[Kernel32ExportsNamesCount][Kernel32ExportsDataCount];
|
||||
|
||||
static LONG OriginalLibraryLoaded = 0;
|
||||
void LoadOriginalLibrary()
|
||||
{
|
||||
if (_InterlockedCompareExchange(&OriginalLibraryLoaded, 1, 0) != 0) return;
|
||||
|
||||
auto szSelfName = GetSelfName();
|
||||
auto szSystemPath = SHGetKnownFolderPath(FOLDERID_System, 0, nullptr) + L'\\' + szSelfName;
|
||||
auto szLocalPath = GetModuleFileNameW(hm); szLocalPath = szLocalPath.substr(0, szLocalPath.find_last_of(L"/\\") + 1);
|
||||
|
||||
if (iequals(szSelfName, L"dnsapi.dll")) {
|
||||
dnsapi.LoadOriginalLibrary(LoadLibraryW(szSystemPath));
|
||||
}
|
||||
}
|
||||
|
||||
void FindFiles(WIN32_FIND_DATAW* fd)
|
||||
{
|
||||
auto dir = GetCurrentDirectoryW();
|
||||
|
||||
HANDLE dvaFile = FindFirstFileW(L"*.dva", fd);
|
||||
if (dvaFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do {
|
||||
if (!(fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
auto pos = wcslen(fd->cFileName);
|
||||
|
||||
if (fd->cFileName[pos - 4] == '.' &&
|
||||
(fd->cFileName[pos - 3] == 'd' || fd->cFileName[pos - 3] == 'D') &&
|
||||
(fd->cFileName[pos - 2] == 'v' || fd->cFileName[pos - 2] == 'V') &&
|
||||
(fd->cFileName[pos - 1] == 'a' || fd->cFileName[pos - 1] == 'A'))
|
||||
{
|
||||
auto path = dir + L'\\' + fd->cFileName;
|
||||
|
||||
if (GetModuleHandle(path.c_str()) == NULL)
|
||||
{
|
||||
auto h = LoadLibraryW(path);
|
||||
SetCurrentDirectoryW(dir.c_str()); //in case dva switched it
|
||||
|
||||
if (h == NULL)
|
||||
{
|
||||
auto e = GetLastError();
|
||||
if (e != ERROR_DLL_INIT_FAILED) // in case dllmain returns false
|
||||
{
|
||||
std::wstring msg = L"Unable to load " + std::wstring(fd->cFileName) + L". Error: " + std::to_wstring(e);
|
||||
MessageBoxW(0, msg.c_str(), L"PD Loader", MB_ICONERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto procedure = (void(*)())GetProcAddress(h, "InitializeDVA");
|
||||
|
||||
if (procedure != NULL)
|
||||
{
|
||||
procedure();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (FindNextFileW(dvaFile, fd));
|
||||
FindClose(dvaFile);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadPlugins()
|
||||
{
|
||||
auto oldDir = GetCurrentDirectoryW(); // store the current directory
|
||||
|
||||
auto szSelfPath = GetModuleFileNameW(hm).substr(0, GetModuleFileNameW(hm).find_last_of(L"/\\") + 1);
|
||||
SetCurrentDirectoryW(szSelfPath.c_str());
|
||||
|
||||
auto nWantsToLoadPlugins = GetPrivateProfileIntW(L"global", L"enable", TRUE, iniPaths);
|
||||
|
||||
if (nWantsToLoadPlugins)
|
||||
{
|
||||
WIN32_FIND_DATAW fd;
|
||||
|
||||
SetCurrentDirectoryW(szSelfPath.c_str());
|
||||
|
||||
if (SetCurrentDirectoryW(L"plugins\\"))
|
||||
FindFiles(&fd);
|
||||
}
|
||||
|
||||
SetCurrentDirectoryW(oldDir.c_str()); // Reset the current directory
|
||||
}
|
||||
|
||||
static LONG LoadedPluginsYet = 0;
|
||||
void LoadEverything()
|
||||
{
|
||||
if (_InterlockedCompareExchange(&LoadedPluginsYet, 1, 0) != 0) return;
|
||||
|
||||
LoadOriginalLibrary();
|
||||
LoadPlugins();
|
||||
}
|
||||
|
||||
static LONG RestoredOnce = 0;
|
||||
void LoadPluginsAndRestoreIAT(uintptr_t retaddr)
|
||||
{
|
||||
bool calledFromBind = false;
|
||||
|
||||
//steam drm check
|
||||
GetSections([&](PIMAGE_SECTION_HEADER pSection, size_t dwLoadOffset, DWORD dwPhysSize) {
|
||||
auto dwStart = static_cast<uintptr_t>(dwLoadOffset + pSection->VirtualAddress);
|
||||
auto dwEnd = dwStart + dwPhysSize;
|
||||
if (retaddr >= dwStart && retaddr <= dwEnd)
|
||||
calledFromBind = true;
|
||||
}, ".bind");
|
||||
|
||||
if (calledFromBind) return;
|
||||
|
||||
if (_InterlockedCompareExchange(&RestoredOnce, 1, 0) != 0) return;
|
||||
|
||||
LoadEverything();
|
||||
|
||||
for (size_t i = 0; i < Kernel32ExportsNamesCount; i++)
|
||||
{
|
||||
if (Kernel32Data[i][IATPtr] && Kernel32Data[i][ProcAddress])
|
||||
{
|
||||
auto ptr = (size_t*)Kernel32Data[i][IATPtr];
|
||||
DWORD dwProtect[2];
|
||||
VirtualProtect(ptr, sizeof(size_t), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
|
||||
*ptr = Kernel32Data[i][ProcAddress];
|
||||
VirtualProtect(ptr, sizeof(size_t), dwProtect[0], &dwProtect[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WINAPI CustomGetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetStartupInfoA(lpStartupInfo);
|
||||
}
|
||||
|
||||
void WINAPI CustomGetStartupInfoW(LPSTARTUPINFOW lpStartupInfo)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetStartupInfoW(lpStartupInfo);
|
||||
}
|
||||
|
||||
HMODULE WINAPI CustomGetModuleHandleA(LPCSTR lpModuleName)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetModuleHandleA(lpModuleName);
|
||||
}
|
||||
|
||||
HMODULE WINAPI CustomGetModuleHandleW(LPCWSTR lpModuleName)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetModuleHandleW(lpModuleName);
|
||||
}
|
||||
|
||||
FARPROC WINAPI CustomGetProcAddress(HMODULE hModule, LPCSTR lpProcName)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetProcAddress(hModule, lpProcName);
|
||||
}
|
||||
|
||||
DWORD WINAPI CustomGetShortPathNameA(LPCSTR lpszLongPath, LPSTR lpszShortPath, DWORD cchBuffer)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetShortPathNameA(lpszLongPath, lpszShortPath, cchBuffer);
|
||||
}
|
||||
|
||||
BOOL WINAPI CustomFindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return FindNextFileA(hFindFile, lpFindFileData);
|
||||
}
|
||||
|
||||
BOOL WINAPI CustomFindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return FindNextFileW(hFindFile, lpFindFileData);
|
||||
}
|
||||
|
||||
HMODULE WINAPI CustomLoadLibraryA(LPCSTR lpLibFileName)
|
||||
{
|
||||
LoadOriginalLibrary();
|
||||
|
||||
return LoadLibraryA(lpLibFileName);
|
||||
}
|
||||
|
||||
HMODULE WINAPI CustomLoadLibraryW(LPCWSTR lpLibFileName)
|
||||
{
|
||||
LoadOriginalLibrary();
|
||||
|
||||
return LoadLibraryW(lpLibFileName);
|
||||
}
|
||||
|
||||
BOOL WINAPI CustomFreeLibrary(HMODULE hLibModule)
|
||||
{
|
||||
if (hLibModule != hm)
|
||||
return FreeLibrary(hLibModule);
|
||||
else
|
||||
return !NULL;
|
||||
}
|
||||
|
||||
HANDLE WINAPI CustomCreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return CreateEventA(lpEventAttributes, bManualReset, bInitialState, lpName);
|
||||
}
|
||||
|
||||
HANDLE WINAPI CustomCreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return CreateEventW(lpEventAttributes, bManualReset, bInitialState, lpName);
|
||||
}
|
||||
|
||||
void WINAPI CustomGetSystemInfo(LPSYSTEM_INFO lpSystemInfo)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return GetSystemInfo(lpSystemInfo);
|
||||
}
|
||||
|
||||
LONG WINAPI CustomInterlockedCompareExchange(LONG volatile* Destination, LONG ExChange, LONG Comperand)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return _InterlockedCompareExchange(Destination, ExChange, Comperand);
|
||||
}
|
||||
|
||||
void WINAPI CustomSleep(DWORD dwMilliseconds)
|
||||
{
|
||||
LoadPluginsAndRestoreIAT((uintptr_t)_ReturnAddress());
|
||||
return Sleep(dwMilliseconds);
|
||||
}
|
||||
|
||||
bool HookKernel32IAT(HMODULE mod, bool exe)
|
||||
{
|
||||
auto hExecutableInstance = (size_t)mod;
|
||||
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)(hExecutableInstance + ((IMAGE_DOS_HEADER*)hExecutableInstance)->e_lfanew);
|
||||
IMAGE_IMPORT_DESCRIPTOR* pImports = (IMAGE_IMPORT_DESCRIPTOR*)(hExecutableInstance + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
size_t nNumImports = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1;
|
||||
|
||||
if (exe)
|
||||
{
|
||||
Kernel32Data[eGetStartupInfoA][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetStartupInfoA");
|
||||
Kernel32Data[eGetStartupInfoW][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetStartupInfoW");
|
||||
Kernel32Data[eGetModuleHandleA][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetModuleHandleA");
|
||||
Kernel32Data[eGetModuleHandleW][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetModuleHandleW");
|
||||
Kernel32Data[eGetProcAddress][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetProcAddress");
|
||||
Kernel32Data[eGetShortPathNameA][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetShortPathNameA");
|
||||
Kernel32Data[eFindNextFileA][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "FindNextFileA");
|
||||
Kernel32Data[eFindNextFileW][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "FindNextFileW");
|
||||
Kernel32Data[eLoadLibraryA][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "LoadLibraryA");
|
||||
Kernel32Data[eLoadLibraryW][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "LoadLibraryW");
|
||||
Kernel32Data[eFreeLibrary][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "FreeLibrary");
|
||||
Kernel32Data[eCreateEventA][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "CreateEventA");
|
||||
Kernel32Data[eCreateEventW][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "CreateEventW");
|
||||
Kernel32Data[eGetSystemInfo][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "GetSystemInfo");
|
||||
Kernel32Data[eInterlockedCompareExchange][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "InterlockedCompareExchange");
|
||||
Kernel32Data[eSleep][ProcAddress] = (size_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), "Sleep");
|
||||
}
|
||||
|
||||
uint32_t matchedImports = 0;
|
||||
|
||||
auto PatchIAT = [&](size_t start, size_t end, size_t exe_end)
|
||||
{
|
||||
for (size_t i = 0; i < nNumImports; i++)
|
||||
{
|
||||
if (hExecutableInstance + (pImports + i)->FirstThunk > start && !(end && hExecutableInstance + (pImports + i)->FirstThunk > end))
|
||||
end = hExecutableInstance + (pImports + i)->FirstThunk;
|
||||
}
|
||||
|
||||
if (!end) { end = start + 0x100; }
|
||||
if (end > exe_end) //for very broken exes
|
||||
{
|
||||
start = hExecutableInstance;
|
||||
end = exe_end;
|
||||
}
|
||||
|
||||
for (auto i = start; i < end; i += sizeof(size_t))
|
||||
{
|
||||
DWORD dwProtect[2];
|
||||
VirtualProtect((size_t*)i, sizeof(size_t), PAGE_EXECUTE_READWRITE, &dwProtect[0]);
|
||||
|
||||
auto ptr = *(size_t*)i;
|
||||
if (!ptr)
|
||||
continue;
|
||||
|
||||
if (ptr == Kernel32Data[eGetStartupInfoA][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetStartupInfoA][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetStartupInfoA;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eGetStartupInfoW][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetStartupInfoW][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetStartupInfoW;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eGetModuleHandleA][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetModuleHandleA][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetModuleHandleA;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eGetModuleHandleW][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetModuleHandleW][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetModuleHandleW;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eGetProcAddress][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetProcAddress][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetProcAddress;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eGetShortPathNameA][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetShortPathNameA][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetShortPathNameA;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eFindNextFileA][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eFindNextFileA][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomFindNextFileA;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eFindNextFileW][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eFindNextFileW][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomFindNextFileW;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eLoadLibraryA][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eLoadLibraryA][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomLoadLibraryA;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eLoadLibraryW][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eLoadLibraryW][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomLoadLibraryW;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eFreeLibrary][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eFreeLibrary][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomFreeLibrary;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eCreateEventA][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eCreateEventA][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomCreateEventA;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eCreateEventW][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eCreateEventW][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomCreateEventW;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eGetSystemInfo][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eGetSystemInfo][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomGetSystemInfo;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eInterlockedCompareExchange][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eInterlockedCompareExchange][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomInterlockedCompareExchange;
|
||||
matchedImports++;
|
||||
}
|
||||
else if (ptr == Kernel32Data[eSleep][ProcAddress])
|
||||
{
|
||||
if (exe) Kernel32Data[eSleep][IATPtr] = i;
|
||||
*(size_t*)i = (size_t)CustomSleep;
|
||||
matchedImports++;
|
||||
}
|
||||
|
||||
VirtualProtect((size_t*)i, sizeof(size_t), dwProtect[0], &dwProtect[1]);
|
||||
}
|
||||
};
|
||||
|
||||
static auto getSection = [](const PIMAGE_NT_HEADERS nt_headers, unsigned section) -> PIMAGE_SECTION_HEADER
|
||||
{
|
||||
return reinterpret_cast<PIMAGE_SECTION_HEADER>(
|
||||
(UCHAR*)nt_headers->OptionalHeader.DataDirectory +
|
||||
nt_headers->OptionalHeader.NumberOfRvaAndSizes * sizeof(IMAGE_DATA_DIRECTORY) +
|
||||
section * sizeof(IMAGE_SECTION_HEADER));
|
||||
};
|
||||
|
||||
static auto getSectionEnd = [](IMAGE_NT_HEADERS* ntHeader, size_t inst) -> auto
|
||||
{
|
||||
auto sec = getSection(ntHeader, ntHeader->FileHeader.NumberOfSections - 1);
|
||||
auto secSize = max(sec->SizeOfRawData, sec->Misc.VirtualSize);
|
||||
auto end = inst + max(sec->PointerToRawData, sec->VirtualAddress) + secSize;
|
||||
return end;
|
||||
};
|
||||
|
||||
auto hExecutableInstance_end = getSectionEnd(ntHeader, hExecutableInstance);
|
||||
|
||||
// Find kernel32.dll
|
||||
for (size_t i = 0; i < nNumImports; i++)
|
||||
{
|
||||
if ((size_t)(hExecutableInstance + (pImports + i)->Name) < hExecutableInstance_end)
|
||||
{
|
||||
if (!_stricmp((const char*)(hExecutableInstance + (pImports + i)->Name), "KERNEL32.DLL"))
|
||||
PatchIAT(hExecutableInstance + (pImports + i)->FirstThunk, 0, hExecutableInstance_end);
|
||||
}
|
||||
}
|
||||
|
||||
// Fixing ordinals
|
||||
auto szSelfName = GetSelfName();
|
||||
|
||||
static auto PatchOrdinals = [&szSelfName](size_t hInstance)
|
||||
{
|
||||
IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)(hInstance + ((IMAGE_DOS_HEADER*)hInstance)->e_lfanew);
|
||||
IMAGE_IMPORT_DESCRIPTOR* pImports = (IMAGE_IMPORT_DESCRIPTOR*)(hInstance + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
|
||||
size_t nNumImports = ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1;
|
||||
|
||||
for (size_t i = 0; i < nNumImports; i++)
|
||||
{
|
||||
if ((size_t)(hInstance + (pImports + i)->Name) < getSectionEnd(ntHeader, (size_t)hInstance))
|
||||
{
|
||||
if (iequals(szSelfName, (to_wstring((const char*)(hInstance + (pImports + i)->Name)))))
|
||||
{
|
||||
PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)(hInstance + (pImports + i)->OriginalFirstThunk);
|
||||
size_t j = 0;
|
||||
while (thunk->u1.Function)
|
||||
{
|
||||
if (thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)
|
||||
{
|
||||
PIMAGE_IMPORT_BY_NAME import = (PIMAGE_IMPORT_BY_NAME)(hInstance + thunk->u1.AddressOfData);
|
||||
void** p = (void**)(hInstance + (pImports + i)->FirstThunk);
|
||||
}
|
||||
++thunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ModuleList dlls;
|
||||
dlls.Enumerate(ModuleList::SearchLocation::LocalOnly);
|
||||
for (auto& e : dlls.m_moduleList)
|
||||
{
|
||||
PatchOrdinals((size_t)std::get<HMODULE>(e));
|
||||
}
|
||||
return matchedImports > 0;
|
||||
}
|
||||
|
||||
LONG WINAPI CustomUnhandledExceptionFilter(LPEXCEPTION_POINTERS ExceptionInfo)
|
||||
{
|
||||
// step 1: write minidump
|
||||
wchar_t modulename[MAX_PATH];
|
||||
wchar_t filename[MAX_PATH];
|
||||
wchar_t timestamp[128];
|
||||
__time64_t time;
|
||||
struct tm ltime;
|
||||
HANDLE hFile;
|
||||
HWND hWnd;
|
||||
|
||||
wchar_t* modulenameptr = NULL;
|
||||
if (GetModuleFileNameW(GetModuleHandle(NULL), modulename, _countof(modulename)) != 0)
|
||||
{
|
||||
modulenameptr = wcsrchr(modulename, '\\');
|
||||
*modulenameptr = L'\0';
|
||||
modulenameptr += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*modulenameptr = L'err.err';
|
||||
}
|
||||
|
||||
_time64(&time);
|
||||
_localtime64_s(<ime, &time);
|
||||
wcsftime(timestamp, _countof(timestamp), L"%Y%m%d%H%M%S", <ime);
|
||||
swprintf_s(filename, L"%s\\%s\\%s.%s.dmp", modulename, L"logs", modulenameptr, timestamp);
|
||||
|
||||
hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
MINIDUMP_EXCEPTION_INFORMATION ex;
|
||||
memset(&ex, 0, sizeof(ex));
|
||||
ex.ThreadId = GetCurrentThreadId();
|
||||
ex.ExceptionPointers = ExceptionInfo;
|
||||
ex.ClientPointers = TRUE;
|
||||
|
||||
if (FAILED(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithDataSegs, &ex, NULL, NULL)))
|
||||
{
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
// step 2: write log
|
||||
// Logs exception into buffer and writes to file
|
||||
swprintf_s(filename, L"%s\\%s\\%s.%s.log", modulename, L"logs", modulenameptr, timestamp);
|
||||
hFile = CreateFileW(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
auto Log = [ExceptionInfo, hFile](char* buffer, size_t size, bool reg, bool stack, bool trace)
|
||||
{
|
||||
if (LogException(buffer, size, (LPEXCEPTION_POINTERS)ExceptionInfo, reg, stack, trace))
|
||||
{
|
||||
DWORD NumberOfBytesWritten = 0;
|
||||
WriteFile(hFile, buffer, strlen(buffer), &NumberOfBytesWritten, NULL);
|
||||
}
|
||||
};
|
||||
|
||||
// Try to make a very descriptive exception, for that we need to malloc a huge buffer...
|
||||
if (auto buffer = (char*)malloc(max_logsize_ever))
|
||||
{
|
||||
Log(buffer, max_logsize_ever, true, true, true);
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use a static buffer, no need for any allocation
|
||||
static const auto size = max_logsize_basic + max_logsize_regs + max_logsize_stackdump;
|
||||
static char static_buf[size];
|
||||
static_assert(size <= max_static_buffer, "Static buffer is too big");
|
||||
|
||||
Log(buffer = static_buf, sizeof(static_buf), true, true, false);
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
// step 3: exit the application
|
||||
ShowCursor(TRUE);
|
||||
hWnd = FindWindowW(0, L"");
|
||||
SetForegroundWindow(hWnd);
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
std::wstring modulePath = GetModuleFileNameW(hm);
|
||||
std::wstring moduleName = modulePath.substr(modulePath.find_last_of(L"/\\") + 1);
|
||||
moduleName.resize(moduleName.find_last_of(L'.'));
|
||||
modulePath.resize(modulePath.find_last_of(L"/\\") + 1);
|
||||
iniPaths.emplace_back(modulePath + moduleName + L".ini");
|
||||
iniPaths.emplace_back(modulePath + L"plugins\\config.ini");
|
||||
|
||||
std::wstring m = GetModuleFileNameW(NULL);
|
||||
m = m.substr(0, m.find_last_of(L"/\\") + 1) + L"logs";
|
||||
|
||||
auto FolderExists = [](LPCWSTR szPath) -> BOOL
|
||||
{
|
||||
DWORD dwAttrib = GetFileAttributes(szPath);
|
||||
return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
};
|
||||
|
||||
if (FolderExists(m.c_str()))
|
||||
{
|
||||
SetUnhandledExceptionFilter(CustomUnhandledExceptionFilter);
|
||||
// Now stub out CustomUnhandledExceptionFilter so NO ONE ELSE can set it!
|
||||
uint32_t ret = 0x909090C3; //ret
|
||||
DWORD protect[2];
|
||||
VirtualProtect(&SetUnhandledExceptionFilter, sizeof(ret), PAGE_EXECUTE_READWRITE, &protect[0]);
|
||||
memcpy(&SetUnhandledExceptionFilter, &ret, sizeof(ret));
|
||||
VirtualProtect(&SetUnhandledExceptionFilter, sizeof(ret), protect[0], &protect[1]);
|
||||
}
|
||||
|
||||
LoadEverything();
|
||||
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
hm = hModule;
|
||||
Init();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,678 @@
|
||||
#pragma once
|
||||
/*
|
||||
* Unhandled Exception Tracer
|
||||
* by LINK/2012 <dma_2012@hotmail.com>
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <cassert>
|
||||
#include <DbgHelp.h>
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
|
||||
/*
|
||||
* Special Note:
|
||||
* Try not to allocate any memory in this file!
|
||||
* Allocation after a exception may not be a good idea...
|
||||
*/
|
||||
|
||||
#define LODWORD(_qw) ((DWORD)(_qw))
|
||||
#define HIDWORD(_qw) ((DWORD)(((_qw) >> 32) & 0xffffffff))
|
||||
|
||||
// General constants
|
||||
static const int sizeof_word = sizeof(void*); // Size of a CPU word (4 bytes on x86)
|
||||
static const int max_chars_per_print = MAX_PATH + 256; // Max characters per Print() call
|
||||
static const int symbol_max = 256; // Max size of a symbol (func symbol, var symbol, etc)
|
||||
static const int max_static_buffer = 4096; // Max static buffer for logging
|
||||
|
||||
// Stackdump constants
|
||||
static const int stackdump_max_words = 60; // max number of CPU words that the stackdump should dump
|
||||
static const int stackdump_words_per_line = 6; // max CPU words in a single line
|
||||
static const int stackdump_line_count = (stackdump_max_words / stackdump_words_per_line) + 1;
|
||||
|
||||
// Backtrace constants
|
||||
static const int max_backtrace_ever = 100;
|
||||
static const int max_backtrace = 20;
|
||||
|
||||
// Maximum log size constants
|
||||
static const int max_logsize_basic = (MAX_PATH + 200); // module path + other text
|
||||
static const int max_logsize_regs = 32 + (4 * 4 * 28); // info + (regsPerLine * numLines * charsPerReg)
|
||||
static const int max_logsize_stackdump = 32 + 80 + (stackdump_line_count * 32) + (10 * stackdump_words_per_line * stackdump_line_count);
|
||||
static const int max_logsize_backtrace = 32 + max_backtrace_ever * (MAX_PATH + symbol_max + 90);
|
||||
static const int max_logsize_ever = 32 + max_logsize_basic + max_logsize_regs + max_logsize_stackdump + max_logsize_backtrace;
|
||||
|
||||
// Internal
|
||||
class ExceptionTracer;
|
||||
class StackTrace;
|
||||
static HMODULE GetModuleFromAddress(LPVOID address);
|
||||
static const char* GetExceptionCodeString(unsigned int code);
|
||||
static const char* FindModuleName(HMODULE module, char* output, DWORD size);
|
||||
static int LogException(char* buffer, size_t max, LPEXCEPTION_POINTERS pException, bool bLogRegisters, bool bLogStack, bool bLogBacktrace);
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER PrevFilter = nullptr;
|
||||
static void(*ExceptionCallback)(const char* buffer) = nullptr;
|
||||
|
||||
// Exportable
|
||||
int InstallExceptionCatcher(void(*OnException)(const char* log));
|
||||
|
||||
/*
|
||||
* ExceptionTrace
|
||||
* This class is responssible for tracing all possible informations about an LPEXCEPTION_POINTER
|
||||
*/
|
||||
class ExceptionTracer
|
||||
{
|
||||
public:
|
||||
ExceptionTracer(char* buffer, size_t max, LPEXCEPTION_POINTERS pException);
|
||||
void PrintUnhandledException();
|
||||
void PrintRegisters();
|
||||
void PrintStackdump();
|
||||
void PrintBacktrace();
|
||||
|
||||
void EnterScope();
|
||||
void LeaveScope();
|
||||
void Print(const char* fmt, ...);
|
||||
void NewLine() { Print("\n%s", spc); }
|
||||
|
||||
protected:
|
||||
EXCEPTION_POINTERS& exception;
|
||||
EXCEPTION_RECORD& record;
|
||||
CONTEXT& context;
|
||||
HMODULE module;
|
||||
|
||||
char* buffer; // Logging buffer
|
||||
size_t len; // Logged length
|
||||
size_t max; // Maximum we can log in that buffer
|
||||
|
||||
char spc[(10 * 4) + 1]; // Scope/spacing buffer, 4 spaces per scope, max 10 scopes
|
||||
size_t nspc; // Number spaces used up there
|
||||
};
|
||||
|
||||
/*
|
||||
* StackTracer
|
||||
* Responssible for backtracing an stack from a context
|
||||
*/
|
||||
class StackTracer
|
||||
{
|
||||
public:
|
||||
struct Trace
|
||||
{
|
||||
// The following values may be null (any)
|
||||
HMODULE module; // The module the func related to this frame is located
|
||||
void* pc; // Program counter at func related to this frame (EIP)
|
||||
void* ret; // Return address for the frame
|
||||
void* frame; // The frame address (EBP)
|
||||
void* stack; // The stack pointer at the frame (ESP)
|
||||
};
|
||||
|
||||
StackTracer(const CONTEXT& context);
|
||||
Trace* Walk();
|
||||
|
||||
private:
|
||||
Trace trace;
|
||||
DWORD old_options;
|
||||
CONTEXT context;
|
||||
STACKFRAME64 frame;
|
||||
};
|
||||
|
||||
/*
|
||||
* TheUnhandledExceptionFilter
|
||||
* Logs an unhandled exception
|
||||
*/
|
||||
static LONG CALLBACK TheUnhandledExceptionFilter(LPEXCEPTION_POINTERS pException)
|
||||
{
|
||||
// Logs exception into buffer and calls the callback
|
||||
auto Log = [pException](char* buffer, size_t size, bool reg, bool stack, bool trace)
|
||||
{
|
||||
if (LogException(buffer, size, (LPEXCEPTION_POINTERS)pException, reg, stack, trace))
|
||||
ExceptionCallback(buffer);
|
||||
};
|
||||
|
||||
// Try to make a very descriptive exception, for that we need to malloc a huge buffer...
|
||||
if (auto buffer = (char*)malloc(max_logsize_ever))
|
||||
{
|
||||
Log(buffer, max_logsize_ever, true, true, true);
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use a static buffer, no need for any allocation
|
||||
static const auto size = max_logsize_basic + max_logsize_regs + max_logsize_stackdump;
|
||||
static char static_buf[size];
|
||||
static_assert(size <= max_static_buffer, "Static buffer is too big");
|
||||
|
||||
Log(buffer = static_buf, sizeof(static_buf), true, true, false);
|
||||
}
|
||||
|
||||
// Continue exception propagation
|
||||
return (PrevFilter ? PrevFilter(pException) : EXCEPTION_CONTINUE_SEARCH); // I'm not really sure about this return
|
||||
}
|
||||
|
||||
/*
|
||||
* InstallExceptionCatcher
|
||||
* Installs a exception handler to call the specified callback when it happens with human readalbe information.
|
||||
*/
|
||||
int InstallExceptionCatcher(void(*cb)(const char* log))
|
||||
{
|
||||
PrevFilter = SetUnhandledExceptionFilter(TheUnhandledExceptionFilter);
|
||||
ExceptionCallback = cb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* LogException
|
||||
* Takes an LPEXCEPTION_POINTERS and transforms in a string that is put in the logging steam
|
||||
*/
|
||||
static int LogException(char* buffer, size_t max, LPEXCEPTION_POINTERS pException, bool bLogRegisters, bool bLogStack, bool bLogBacktrace)
|
||||
{
|
||||
ExceptionTracer trace(buffer, max, pException);
|
||||
trace.PrintUnhandledException();
|
||||
trace.EnterScope();
|
||||
if (bLogRegisters) trace.PrintRegisters();
|
||||
if (bLogStack) trace.PrintStackdump();
|
||||
if (bLogBacktrace) trace.PrintBacktrace();
|
||||
trace.LeaveScope();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ExceptionTracer
|
||||
* Contructs a exception trace object, responssible for tracing informations about an exception
|
||||
*/
|
||||
ExceptionTracer::ExceptionTracer(char* buffer, size_t max, LPEXCEPTION_POINTERS pException) :
|
||||
buffer(buffer), exception(*pException), record(*pException->ExceptionRecord), context(*pException->ContextRecord)
|
||||
{
|
||||
this->buffer = buffer;
|
||||
this->buffer[this->len = 0] = 0;
|
||||
this->spc[this->nspc = 0] = 0;
|
||||
this->max = max;
|
||||
|
||||
// Acquiere common information that we'll access
|
||||
this->module = GetModuleFromAddress(record.ExceptionAddress);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print
|
||||
* Prints some formated text into the logging buffer
|
||||
*/
|
||||
void ExceptionTracer::Print(const char* fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
if ((this->max - this->len) > max_chars_per_print)
|
||||
this->len += vsprintf(&this->buffer[len], fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
/*
|
||||
* EnterScope
|
||||
* Enters a new scope in the logging buffer (scope is related to indentation)
|
||||
* This also prints a new line
|
||||
*/
|
||||
void ExceptionTracer::EnterScope()
|
||||
{
|
||||
nspc += 4;
|
||||
spc[nspc - 4] = ' ';
|
||||
spc[nspc - 3] = ' ';
|
||||
spc[nspc - 2] = ' ';
|
||||
spc[nspc - 1] = ' ';
|
||||
spc[nspc - 0] = 0;
|
||||
NewLine();
|
||||
}
|
||||
|
||||
/*
|
||||
* LeaveScope
|
||||
* Leaves the scope
|
||||
*/
|
||||
void ExceptionTracer::LeaveScope()
|
||||
{
|
||||
assert(nspc > 0);
|
||||
nspc -= 4;
|
||||
spc[nspc] = 0;
|
||||
NewLine();
|
||||
}
|
||||
|
||||
/*
|
||||
* PrintUnhandledException
|
||||
* Prints the well known "Unhandled exception at ..." into the logging buffer
|
||||
*/
|
||||
void ExceptionTracer::PrintUnhandledException()
|
||||
{
|
||||
char module_name[MAX_PATH];
|
||||
auto dwExceptionCode = record.ExceptionCode;
|
||||
uintptr_t address = (uintptr_t)record.ExceptionAddress;
|
||||
|
||||
// Find out our module name for logging
|
||||
if (!this->module || !GetModuleFileNameA(this->module, module_name, sizeof(module_name)))
|
||||
strcpy(module_name, "unknown");
|
||||
|
||||
// Log the exception in a similar format similar to debuggers format
|
||||
Print("Unhandled exception at 0x%p in %s", address, FindModuleName(module, module_name, sizeof(module_name)));
|
||||
if (module) Print(" (+0x%x)", address - (uintptr_t)(module));
|
||||
Print(": 0x%X: %s", dwExceptionCode, GetExceptionCodeString(dwExceptionCode));
|
||||
|
||||
// If exception is IN_PAGE_ERROR or ACCESS_VIOLATION, we have additional information such as an address
|
||||
if (dwExceptionCode == EXCEPTION_IN_PAGE_ERROR || dwExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
auto rw = (DWORD)record.ExceptionInformation[0]; // read or write?
|
||||
auto addr = (ULONG_PTR)record.ExceptionInformation[1]; // which address?
|
||||
|
||||
Print(" %s 0x%p",
|
||||
rw == 0 ? "reading location" : rw == 1 ? "writing location" : rw == 8 ? "DEP at" : "",
|
||||
addr);
|
||||
|
||||
// IN_PAGE_ERROR have another information...
|
||||
if (dwExceptionCode == EXCEPTION_IN_PAGE_ERROR)
|
||||
{
|
||||
NewLine();
|
||||
Print("Underlying NTSTATUS code that resulted in the exception is 0x%p",
|
||||
record.ExceptionInformation[2]);
|
||||
}
|
||||
}
|
||||
|
||||
Print(".");
|
||||
}
|
||||
|
||||
/*
|
||||
* PrintRegisters
|
||||
* Prints the content of the assembly registers into the logging buffer
|
||||
*/
|
||||
void ExceptionTracer::PrintRegisters()
|
||||
{
|
||||
int regs_in_line = 0; // Amount of registers currently printed on this line
|
||||
|
||||
// Prints a register, followed by spaces
|
||||
auto PrintRegister = [this, ®s_in_line](const char* reg_name, size_t reg_value, const char* spaces)
|
||||
{
|
||||
Print("%s: 0x%p%s", reg_name, reg_value, spaces);
|
||||
if (++regs_in_line >= 4) { this->NewLine(); regs_in_line = 0; }
|
||||
};
|
||||
|
||||
auto PrintFloatRegister = [this, ®s_in_line](const char* reg_name, int reg_num, uint32_t reg_value1, uint32_t reg_value2, uint32_t reg_value3, uint32_t reg_value4)
|
||||
{
|
||||
Print("%s%02d: 0x%08X 0x%08X 0x%08X 0x%08X [ %f %f %f %f ]", reg_name, reg_num, reg_value1, reg_value2, reg_value3, reg_value4,
|
||||
*(float*)& reg_value1, *(float*)& reg_value2, *(float*)& reg_value3, *(float*)& reg_value4);
|
||||
if (++regs_in_line >= 1) { this->NewLine(); regs_in_line = 0; }
|
||||
};
|
||||
|
||||
// Prints a general purposes register
|
||||
auto PrintIntRegister = [PrintRegister](const char* reg_name, size_t reg_value)
|
||||
{
|
||||
PrintRegister(reg_name, reg_value, " ");
|
||||
};
|
||||
|
||||
// Prints a segment register
|
||||
auto PrintSegRegister = [PrintRegister](const char* reg_name, size_t reg_value)
|
||||
{
|
||||
PrintRegister(reg_name, reg_value, " ");
|
||||
};
|
||||
|
||||
Print("Register dump:");
|
||||
EnterScope();
|
||||
{
|
||||
// Print main general purposes registers
|
||||
if (context.ContextFlags & CONTEXT_INTEGER)
|
||||
{
|
||||
#if !_M_X64
|
||||
PrintIntRegister("EAX", context.Eax);
|
||||
PrintIntRegister("EBX", context.Ebx);
|
||||
PrintIntRegister("ECX", context.Ecx);
|
||||
PrintIntRegister("EDX", context.Edx);
|
||||
PrintIntRegister("EDI", context.Edi);
|
||||
PrintIntRegister("ESI", context.Esi);
|
||||
#else
|
||||
PrintIntRegister("RAX", context.Rax);
|
||||
PrintIntRegister("RCX", context.Rcx);
|
||||
PrintIntRegister("RDX", context.Rdx);
|
||||
PrintIntRegister("RBX", context.Rbx);
|
||||
PrintIntRegister("RBP", context.Rbp);
|
||||
PrintIntRegister("RSI", context.Rsi);
|
||||
PrintIntRegister("RDI", context.Rdi);
|
||||
PrintIntRegister("R08", context.R8);
|
||||
PrintIntRegister("R09", context.R9);
|
||||
PrintIntRegister("R10", context.R10);
|
||||
PrintIntRegister("R11", context.R11);
|
||||
PrintIntRegister("R12", context.R12);
|
||||
PrintIntRegister("R13", context.R13);
|
||||
PrintIntRegister("R14", context.R14);
|
||||
PrintIntRegister("R15", context.R15);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Print control registers
|
||||
if (context.ContextFlags & CONTEXT_CONTROL)
|
||||
{
|
||||
#if !_M_X64
|
||||
PrintIntRegister("EBP", context.Ebp);
|
||||
PrintIntRegister("EIP", context.Eip);
|
||||
PrintIntRegister("ESP", context.Esp);
|
||||
PrintIntRegister("EFL", context.EFlags);
|
||||
this->NewLine(); this->NewLine(); regs_in_line = 0;
|
||||
PrintSegRegister("CS", context.SegCs);
|
||||
PrintSegRegister("SS", context.SegSs);
|
||||
#else
|
||||
PrintIntRegister("RIP", context.Rip);
|
||||
PrintIntRegister("RSP", context.Rsp);
|
||||
PrintIntRegister("EFL", context.EFlags);
|
||||
this->NewLine(); this->NewLine(); regs_in_line = 0;
|
||||
PrintSegRegister("CS", context.SegCs);
|
||||
PrintSegRegister("SS", context.SegSs);
|
||||
#endif
|
||||
}
|
||||
|
||||
this->NewLine(); regs_in_line = 0;
|
||||
|
||||
// Print segment registers
|
||||
if (context.ContextFlags & CONTEXT_SEGMENTS)
|
||||
{
|
||||
PrintSegRegister("GS", context.SegGs);
|
||||
PrintSegRegister("FS", context.SegFs);
|
||||
this->NewLine(); regs_in_line = 0;
|
||||
PrintSegRegister("ES", context.SegEs);
|
||||
PrintSegRegister("DS", context.SegDs);
|
||||
}
|
||||
|
||||
this->NewLine(); this->NewLine(); regs_in_line = 0;
|
||||
|
||||
// Print floating point registers
|
||||
if (context.ContextFlags & CONTEXT_FLOATING_POINT)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
#if !_M_X64
|
||||
auto f = *(M128A*) & (context.FloatSave.RegisterArea[i * 10]);
|
||||
PrintFloatRegister("ST", i, LODWORD(f.Low), HIDWORD(f.Low), LODWORD(f.High), HIDWORD(f.High));
|
||||
#else
|
||||
PrintFloatRegister("ST", i,
|
||||
LODWORD(context.FltSave.FloatRegisters[i].Low), HIDWORD(context.FltSave.FloatRegisters[i].Low),
|
||||
LODWORD(context.FltSave.FloatRegisters[i].High), HIDWORD(context.FltSave.FloatRegisters[i].High));
|
||||
#endif
|
||||
}
|
||||
|
||||
this->NewLine();
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
#if !_M_X64
|
||||
auto f = *(M128A*) & (context.ExtendedRegisters[(i + 10) * 16]);
|
||||
PrintFloatRegister("XMM", i, LODWORD(f.Low), HIDWORD(f.Low), LODWORD(f.High), HIDWORD(f.High));
|
||||
|
||||
if (i >= 7)
|
||||
break;
|
||||
#else
|
||||
PrintFloatRegister("XMM", i,
|
||||
LODWORD(context.FltSave.XmmRegisters[i].Low), HIDWORD(context.FltSave.XmmRegisters[i].Low),
|
||||
LODWORD(context.FltSave.XmmRegisters[i].High), HIDWORD(context.FltSave.XmmRegisters[i].High));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveScope();
|
||||
}
|
||||
|
||||
/*
|
||||
* PrintStackdump
|
||||
* Prints the content of the stack into the logging buffer
|
||||
*/
|
||||
void ExceptionTracer::PrintStackdump()
|
||||
{
|
||||
// We need the ESP of the exception context to execute a stack dump, make sure we have access to it
|
||||
if ((context.ContextFlags & CONTEXT_CONTROL) == 0)
|
||||
return;
|
||||
|
||||
static const auto align = sizeof_word; // Stack aligment
|
||||
static const auto max_words_in_line_magic = stackdump_words_per_line + 10;
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
#if !_M_X64
|
||||
uintptr_t base, bottom, top = (uintptr_t)context.Esp;
|
||||
#else
|
||||
uintptr_t base, bottom, top = (uintptr_t)context.Rsp;
|
||||
#endif
|
||||
auto words_in_line = max_words_in_line_magic;
|
||||
|
||||
// Finds the bottom of the stack from it's base pointer
|
||||
// Note: mbi will get overriden on this function
|
||||
auto GetStackBottom = [&mbi](uintptr_t base)
|
||||
{
|
||||
VirtualQuery((void*)base, &mbi, sizeof(mbi)); // Find uncommited region of the stack
|
||||
VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi)); // Find guard page
|
||||
VirtualQuery((char*)mbi.BaseAddress + mbi.RegionSize, &mbi, sizeof(mbi)); // Find commited region of the stack
|
||||
auto last = (uintptr_t)mbi.BaseAddress;
|
||||
return (base + (last - base) + mbi.RegionSize); // base + distanceToLastRegion + lastRegionSize
|
||||
};
|
||||
|
||||
// Prints an CPU word at the specified stack address
|
||||
auto PrintWord = [this, &words_in_line](uintptr_t addr)
|
||||
{
|
||||
if (words_in_line++ >= stackdump_words_per_line)
|
||||
{
|
||||
// Print new line only if it's not the first time we enter here (i.e. words_in_line has magical value)
|
||||
if (words_in_line != max_words_in_line_magic + 1) NewLine();
|
||||
words_in_line = 1;
|
||||
Print("0x%p: ", addr);
|
||||
}
|
||||
Print(" %p", *(size_t*)addr);
|
||||
};
|
||||
|
||||
Print("Stack dump:");
|
||||
EnterScope();
|
||||
{
|
||||
// Makes sure the pointer at top (ESP) is valid and readable memory
|
||||
if (VirtualQuery((void*)(top), &mbi, sizeof(mbi))
|
||||
&& (mbi.State & MEM_COMMIT)
|
||||
&& (mbi.Protect & (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_READWRITE | PAGE_READONLY)) != 0)
|
||||
{
|
||||
base = (uintptr_t)mbi.AllocationBase; // Base of the stack (uncommited)
|
||||
bottom = GetStackBottom(base); // Bottom of the stack (commited)
|
||||
|
||||
// Align the stack top (esp) in a 4 bytes boundary
|
||||
auto remainder = top % align;
|
||||
uintptr_t current = remainder ? top + (align - remainder) : top;
|
||||
|
||||
// on x86 stack grows downward! (i.e. from bottom to base)
|
||||
for (int n = 0; n < stackdump_max_words && current < bottom; ++n, current += align)
|
||||
PrintWord(current);
|
||||
|
||||
NewLine();
|
||||
Print("base: 0x%p top: 0x%p bottom: 0x%p", base, top, bottom);
|
||||
NewLine();
|
||||
}
|
||||
}
|
||||
LeaveScope();
|
||||
}
|
||||
|
||||
/*
|
||||
* PrintBacktrace
|
||||
* Prints a call backtrace into the logging buffer
|
||||
*/
|
||||
void ExceptionTracer::PrintBacktrace()
|
||||
{
|
||||
StackTracer tracer(this->context);
|
||||
|
||||
char module_name[MAX_PATH];
|
||||
char sym_buffer[sizeof(SYMBOL_INFO) + symbol_max];
|
||||
|
||||
int backtrace_count = 0; // Num of frames traced
|
||||
bool has_symbol_api = false; // True if we have the symbol API available for use
|
||||
DWORD old_options; // Saves old symbol API options
|
||||
|
||||
SYMBOL_INFO& symbol = *(SYMBOL_INFO*)sym_buffer;
|
||||
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol.MaxNameLen = symbol_max;
|
||||
|
||||
// Tries to get the symbol api
|
||||
if (SymInitialize(GetCurrentProcess(), 0, TRUE))
|
||||
{
|
||||
has_symbol_api = true;
|
||||
old_options = SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_NO_PROMPTS | SYMOPT_FAIL_CRITICAL_ERRORS);
|
||||
}
|
||||
|
||||
Print("Backtrace (may be wrong):");
|
||||
EnterScope();
|
||||
{
|
||||
// Walks on the stack until there's no frame to trace or we traced 'max_backtrace' frames
|
||||
while (auto trace = tracer.Walk())
|
||||
{
|
||||
if (++backtrace_count >= max_backtrace)
|
||||
break;
|
||||
|
||||
bool has_sym = false; // This EIP has a symbol associated with it?
|
||||
DWORD64 displacement; // EIP displacement relative to symbol
|
||||
|
||||
// If we have access to the symbol api, try to get symbol name from pc (eip)
|
||||
if (has_symbol_api)
|
||||
has_sym = trace->pc ? !!SymFromAddr(GetCurrentProcess(), (DWORD64)trace->pc, &displacement, &symbol) : false;
|
||||
|
||||
// Print everything up, this.... Ew, this looks awful!
|
||||
Print(backtrace_count == 1 ? "=>" : " "); // First line should have '=>' to specify where it crashed
|
||||
Print("0x%p ", trace->pc); // Print EIP at frame
|
||||
if (has_sym) Print("%s+0x%x ", symbol.Name, (DWORD)displacement); // Print frame func symbol
|
||||
Print("in %s (+0x%x) ", // Print module
|
||||
trace->module ? FindModuleName(trace->module, module_name, sizeof(module_name)) : "unknown",
|
||||
(uintptr_t)(trace->pc) - (uintptr_t)(trace->module) // Module displacement
|
||||
);
|
||||
if (trace->frame) Print("(0x%p) ", trace->frame); // Print frame pointer
|
||||
|
||||
NewLine();
|
||||
}
|
||||
}
|
||||
LeaveScope();
|
||||
|
||||
// Cleanup the symbol api
|
||||
if (has_symbol_api)
|
||||
{
|
||||
SymSetOptions(old_options);
|
||||
SymCleanup(GetCurrentProcess());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GetExceptionCodeString
|
||||
* Returns an description by an exception code
|
||||
*/
|
||||
static const char* GetExceptionCodeString(unsigned int code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION: return "Access violation";
|
||||
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "Array bounds exceeded";
|
||||
case EXCEPTION_BREAKPOINT: return "Breakpoint exception";
|
||||
case EXCEPTION_DATATYPE_MISALIGNMENT: return "Data type misalignment exception";
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND: return "Denormal float operand";
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "Floating-point division by zero";
|
||||
case EXCEPTION_FLT_INEXACT_RESULT: return "Floating-point inexact result";
|
||||
case EXCEPTION_FLT_INVALID_OPERATION: return "Floating-point invalid operation";
|
||||
case EXCEPTION_FLT_OVERFLOW: return "Floating-point overflow";
|
||||
case EXCEPTION_FLT_STACK_CHECK: return "Floating-point stack check";
|
||||
case EXCEPTION_FLT_UNDERFLOW: return "Floating-point underflow";
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION: return "Illegal instruction.";
|
||||
case EXCEPTION_IN_PAGE_ERROR: return "In page error";
|
||||
case EXCEPTION_INT_DIVIDE_BY_ZERO: return "Integer division by zero";
|
||||
case EXCEPTION_INT_OVERFLOW: return "Integer overflow";
|
||||
case EXCEPTION_INVALID_DISPOSITION: return "Invalid disposition";
|
||||
case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "Non-continuable exception";
|
||||
case EXCEPTION_PRIV_INSTRUCTION: return "Privileged instruction";
|
||||
case EXCEPTION_SINGLE_STEP: return "Single step exception";
|
||||
case EXCEPTION_STACK_OVERFLOW: return "Stack overflow";
|
||||
default: return "NO_DESCRIPTION";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FindModuleName
|
||||
* Finds module filename or "unknown"
|
||||
*/
|
||||
static const char* FindModuleName(HMODULE module, char* output, DWORD maxsize)
|
||||
{
|
||||
if (GetModuleFileNameA(module, output, maxsize))
|
||||
{
|
||||
// Finds the filename part in the output string
|
||||
char* filename = strrchr(output, '\\');
|
||||
if (!filename) filename = strrchr(output, '/');
|
||||
|
||||
// If filename found (i.e. output isn't already a filename but full path), make output be filename
|
||||
if (filename)
|
||||
{
|
||||
size_t size = strlen(++filename);
|
||||
memmove(output, filename, size);
|
||||
output[size] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown module
|
||||
strcpy(output, "unknown");
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/*
|
||||
* GetModuleFromAddress
|
||||
* Finds module handle from some address inside it
|
||||
*/
|
||||
static HMODULE GetModuleFromAddress(LPVOID address)
|
||||
{
|
||||
HMODULE module;
|
||||
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(char*)address, &module))
|
||||
return module;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* StackTracer
|
||||
* Constructs the tracer, we basically need to initialize the symbol api
|
||||
*/
|
||||
StackTracer::StackTracer(const CONTEXT& context)
|
||||
{
|
||||
// Initialise basic values
|
||||
memset(&this->frame, 0, sizeof(frame));
|
||||
memcpy(&this->context, &context, sizeof(context));
|
||||
|
||||
// Setup the initial frame context
|
||||
#if !_M_X64
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrPC.Offset = context.Eip;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Ebp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = context.Esp;
|
||||
#else
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrPC.Offset = context.Rip;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Rbp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = context.Rsp;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* StackTracer::Walk
|
||||
* Walks on the stack, each walk is one frame of backtrace
|
||||
* Returns a frame or null if the walk on the park is not possible anymore
|
||||
*/
|
||||
StackTracer::Trace* StackTracer::Walk()
|
||||
{
|
||||
if (StackWalk64(IMAGE_FILE_MACHINE_I386, GetCurrentProcess(), GetCurrentThread(),
|
||||
&frame, &context, NULL, NULL, NULL, NULL))
|
||||
{
|
||||
trace.module = GetModuleFromAddress((void*)frame.AddrPC.Offset);
|
||||
trace.frame = (void*)frame.AddrFrame.Offset;
|
||||
trace.stack = (void*)frame.AddrStack.Offset;
|
||||
trace.pc = (void*)frame.AddrPC.Offset;
|
||||
trace.ret = (void*)frame.AddrReturn.Offset;
|
||||
return &trace;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <shlobj.h>
|
||||
#include <set>
|
||||
#include "ModuleList.h"
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_ReturnAddress)
|
||||
|
||||
struct shared
|
||||
{
|
||||
FARPROC DllCanUnloadNow;
|
||||
FARPROC DllGetClassObject;
|
||||
FARPROC DllRegisterServer;
|
||||
FARPROC DllUnregisterServer;
|
||||
FARPROC DebugSetMute;
|
||||
|
||||
void LoadOriginalLibrary(HMODULE dll)
|
||||
{
|
||||
DllCanUnloadNow = GetProcAddress(dll, "DllCanUnloadNow");
|
||||
DllGetClassObject = GetProcAddress(dll, "DllGetClassObject");
|
||||
DllRegisterServer = GetProcAddress(dll, "DllRegisterServer");
|
||||
DllUnregisterServer = GetProcAddress(dll, "DllUnregisterServer");
|
||||
DebugSetMute = GetProcAddress(dll, "DebugSetMute");
|
||||
}
|
||||
} shared;
|
||||
|
||||
struct dnsapi_dll
|
||||
{
|
||||
HMODULE dll;
|
||||
|
||||
// only some functions are implemented.
|
||||
// PDAFT doesn't use many, so this should hopefully be fine
|
||||
FARPROC DnsFree;
|
||||
FARPROC DnsQuery_A;
|
||||
FARPROC DnsQueryEx;
|
||||
FARPROC DnsCancelQuery;
|
||||
|
||||
// DnsQueryEx and DnsCancelQuery take pointers to structs as parameters
|
||||
// (three for DnsQueryEx and one for DnsCancelQuery)
|
||||
// fortunately they should fit in registers so the stack doesn't matter
|
||||
// hopefully this works fine... I have no clue what I'm doing
|
||||
static LONG WINAPI DnsQueryExStub()
|
||||
{
|
||||
return 9004; // DNS_ERROR_RCODE_NOT_IMPLEMENTED
|
||||
}
|
||||
static LONG WINAPI DnsCancelQueryStub()
|
||||
{
|
||||
return 9004; // DNS_ERROR_RCODE_NOT_IMPLEMENTED
|
||||
}
|
||||
|
||||
void LoadOriginalLibrary(HMODULE module)
|
||||
{
|
||||
dll = module;
|
||||
shared.LoadOriginalLibrary(dll);
|
||||
DnsFree = GetProcAddress(dll, "DnsFree");
|
||||
DnsQuery_A = GetProcAddress(dll, "DnsQuery_A");
|
||||
DnsQueryEx = GetProcAddress(dll, "DnsQueryEx");
|
||||
DnsCancelQuery = GetProcAddress(dll, "DnsCancelQuery");
|
||||
|
||||
// if entry points aren't found, GetProcAddress should return null
|
||||
// I hope this is correct
|
||||
// Thanks to somewhatlurker
|
||||
if (DnsQueryEx == NULL) { DnsQueryEx = (FARPROC)& DnsQueryExStub; };
|
||||
if (DnsCancelQuery == NULL) { DnsCancelQuery = (FARPROC)& DnsCancelQueryStub; };
|
||||
}
|
||||
} dnsapi;
|
||||
|
||||
void _DnsFree() { dnsapi.DnsFree(); }
|
||||
void _DnsQuery_A() { dnsapi.DnsQuery_A(); }
|
||||
void _DnsQueryEx() { dnsapi.DnsQueryEx(); }
|
||||
void _DnsCancelQuery() { dnsapi.DnsCancelQuery(); }
|
||||
|
||||
#pragma runtime_checks( "", off )
|
||||
|
||||
#ifdef _DEBUG
|
||||
#pragma message ("You are compiling the code in Debug - be warned that wrappers for export functions may not have correct code generated")
|
||||
#endif
|
||||
|
||||
void _DllRegisterServer() { shared.DllRegisterServer(); }
|
||||
void _DllUnregisterServer() { shared.DllUnregisterServer(); }
|
||||
void _DllCanUnloadNow() { shared.DllCanUnloadNow(); }
|
||||
void _DllGetClassObject() { shared.DllGetClassObject(); }
|
||||
|
||||
#pragma runtime_checks( "", restore )
|
||||
@@ -0,0 +1,10 @@
|
||||
LIBRARY "dnsapi"
|
||||
EXPORTS
|
||||
DnsFree = _DnsFree
|
||||
DnsQuery_A = _DnsQuery_A
|
||||
DnsQueryEx = _DnsQueryEx
|
||||
DnsCancelQuery = _DnsCancelQuery
|
||||
DllCanUnloadNow = _DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject = _DllGetClassObject PRIVATE
|
||||
DllRegisterServer = _DllRegisterServer PRIVATE
|
||||
DllUnregisterServer = _DllUnregisterServer PRIVATE
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ui.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="constants.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{60d5e9f4-335f-402b-9a07-d78674dffc9b}</ProjectGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<Keyword>ManagedCProj</Keyword>
|
||||
<RootNamespace>Launcher</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Launcher</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CLRSupport>true</CLRSupport>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
<TargetName>$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;..\..\..\dependencies\freeglut\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>User32.lib</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies />
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>main</EntryPointSymbol>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\detours\include;..\..\..\dependencies\freeglut\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>User32.lib</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="TabPadding.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="TabPadding.h" />
|
||||
<ClInclude Include="ui.h">
|
||||
<FileType>CppForm</FileType>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="ui.resx">
|
||||
<DependentUpon>ui.h</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "TabPadding.h"
|
||||
//#include <Windows.h>
|
||||
|
||||
// ported from https://stackoverflow.com/a/7785745
|
||||
// original code by user LarsTech https://stackoverflow.com/users/719186/larstech
|
||||
|
||||
TabPadding::TabPadding(TabControl^ tc)
|
||||
{
|
||||
tabControl = tc;
|
||||
tabControl->Selected += gcnew TabControlEventHandler(this, &TabPadding::tabControl_Selected);
|
||||
AssignHandle(tc->Handle);
|
||||
}
|
||||
|
||||
void TabPadding::tabControl_Selected(Object^ sender, TabControlEventArgs^ e)
|
||||
{
|
||||
tabControl->Invalidate();
|
||||
}
|
||||
|
||||
void TabPadding::WndProc(Message %m) {
|
||||
NativeWindow::WndProc(m);
|
||||
|
||||
if (m.Msg == 15) { //WM_PAINT
|
||||
Graphics^ g = Graphics::FromHwnd(m.HWnd);
|
||||
|
||||
//Replace the outside white borders:
|
||||
if (tabControl->Parent) {
|
||||
g->SetClip(System::Drawing::Rectangle(0, 0, tabControl->Width - 2, tabControl->Height - 1), Drawing2D::CombineMode::Exclude);
|
||||
g->FillRectangle(gcnew SolidBrush(tabControl->Parent->BackColor),
|
||||
System::Drawing::Rectangle(0, tabControl->ItemSize.Height + 2, tabControl->Width, tabControl->Height - (tabControl->ItemSize.Height + 2)));
|
||||
}
|
||||
|
||||
|
||||
//Replace the inside white borders:
|
||||
if (tabControl->SelectedTab) {
|
||||
g->ResetClip();
|
||||
System::Drawing::Rectangle r = tabControl->SelectedTab->Bounds;
|
||||
g->SetClip(r, Drawing2D::CombineMode::Exclude);
|
||||
g->FillRectangle(gcnew SolidBrush(tabControl->SelectedTab->BackColor),
|
||||
System::Drawing::Rectangle(r.Left - 3, r.Top - 1, r.Width + 4, r.Height + 3));
|
||||
}
|
||||
|
||||
delete g;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
using namespace System::Windows::Forms;
|
||||
using namespace System::Drawing;
|
||||
|
||||
// ported from https://stackoverflow.com/a/7785745
|
||||
// original code by user LarsTech https://stackoverflow.com/users/719186/larstech
|
||||
|
||||
ref class TabPadding : public NativeWindow
|
||||
{
|
||||
public:
|
||||
TabPadding(TabControl^ tc);
|
||||
|
||||
private:
|
||||
TabControl^ tabControl;
|
||||
void tabControl_Selected(Object^ sender, TabControlEventArgs^ e);
|
||||
|
||||
protected:
|
||||
virtual void WndProc(Message %m) override;
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 229 KiB |
@@ -0,0 +1,45 @@
|
||||
#include "ui.h"
|
||||
#include "framework.h"
|
||||
#include <detours.h>
|
||||
#pragma comment(lib, "detours.lib")
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Windows::Forms;
|
||||
|
||||
[STAThread]
|
||||
int showUI() {
|
||||
if (Environment::OSVersion->Version->Major >= 6)
|
||||
SetProcessDPIAware();
|
||||
|
||||
Application::EnableVisualStyles();
|
||||
Application::SetCompatibleTextRenderingDefault(false);
|
||||
Application::Run(gcnew Launcher::ui());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hookedMain(int argc, const char** argv, const char** envp)
|
||||
{
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
arg = argv[i];
|
||||
if (arg == "--launch" || nSkipLauncher)
|
||||
return divaMain(argc, argv, envp);
|
||||
}
|
||||
return showUI();
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)divaMain, hookedMain);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
int (__cdecl* divaMain)(int argc, const char** argv, const char** envp) = (int(__cdecl*)(int argc, const char** argv, const char** envp))0x140194D90;
|
||||
|
||||
using namespace std;
|
||||
|
||||
string arg;
|
||||
|
||||
wstring ExePath() {
|
||||
WCHAR buffer[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
||||
return wstring(buffer);
|
||||
}
|
||||
|
||||
wstring DirPath() {
|
||||
wstring exepath = ExePath();
|
||||
wstring::size_type pos = exepath.find_last_of(L"\\/");
|
||||
return exepath.substr(0, pos);
|
||||
}
|
||||
|
||||
wstring DIVA_EXECUTABLE_STRING = ExePath();
|
||||
LPCWSTR DIVA_EXECUTABLE = DIVA_EXECUTABLE_STRING.c_str();
|
||||
|
||||
wstring DIVA_EXECUTABLE_LAUNCH_STRING = DIVA_EXECUTABLE_STRING + L" --launch";
|
||||
LPWSTR DIVA_EXECUTABLE_LAUNCH = const_cast<WCHAR*>(DIVA_EXECUTABLE_LAUNCH_STRING.c_str());
|
||||
|
||||
wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\config.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
|
||||
int nDisplay = GetPrivateProfileIntW(L"resolution", L"display", 0, CONFIG_FILE);
|
||||
int nWidth = GetPrivateProfileIntW(L"resolution", L"width", 1280, CONFIG_FILE);
|
||||
int nHeight = GetPrivateProfileIntW(L"resolution", L"height", 720, CONFIG_FILE);
|
||||
|
||||
int nIntRes = GetPrivateProfileIntW(L"resolution", L"r.enable", FALSE, CONFIG_FILE);
|
||||
int nIntResWidth = GetPrivateProfileIntW(L"resolution", L"r.width", 1280, CONFIG_FILE);
|
||||
int nIntResHeight = GetPrivateProfileIntW(L"resolution", L"r.height", 720, CONFIG_FILE);
|
||||
|
||||
int nBitDepth = GetPrivateProfileIntW(L"resolution", L"bitdepth", 32, CONFIG_FILE);
|
||||
int nRefreshRate = GetPrivateProfileIntW(L"resolution", L"refreshrate", 60, CONFIG_FILE);
|
||||
|
||||
int nCursor = GetPrivateProfileIntW(L"patches", L"cursor", TRUE, CONFIG_FILE);
|
||||
int nHideFreeplay = GetPrivateProfileIntW(L"patches", L"hide_freeplay", FALSE, CONFIG_FILE);
|
||||
int nStatusIcons = GetPrivateProfileIntW(L"patches", L"status_icons", 0, CONFIG_FILE);
|
||||
int nHidePVWatermark = GetPrivateProfileIntW(L"patches", L"hide_pv_watermark", FALSE, CONFIG_FILE);
|
||||
int nNoPVUi = GetPrivateProfileIntW(L"patches", L"no_pv_ui", FALSE, CONFIG_FILE);
|
||||
int nHideVolCtrl = GetPrivateProfileIntW(L"patches", L"hide_volume", FALSE, CONFIG_FILE);
|
||||
int nNoLyrics = GetPrivateProfileIntW(L"patches", L"no_lyrics", FALSE, CONFIG_FILE);
|
||||
int nNoMovies = GetPrivateProfileIntW(L"patches", L"no_movies", FALSE, CONFIG_FILE);
|
||||
int nNoError = GetPrivateProfileIntW(L"patches", L"no_error", TRUE, CONFIG_FILE);
|
||||
|
||||
int nTAA = GetPrivateProfileIntW(L"graphics", L"TAA", TRUE, CONFIG_FILE);
|
||||
int nMLAA = GetPrivateProfileIntW(L"graphics", L"MLAA", TRUE, CONFIG_FILE);
|
||||
int nFPSLimit = GetPrivateProfileIntW(L"graphics", L"FPS.Limit", 0, CONFIG_FILE);
|
||||
|
||||
int nSkipLauncher = GetPrivateProfileIntW(L"launcher", L"skip", FALSE, CONFIG_FILE);
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,172 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{3FD6ACA9-E613-4FD6-BDA2-55A91C2CF65C}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Patches</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;PATCHES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\freeglut\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;PATCHES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;PATCHES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\freeglut\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;PATCHES_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,211 @@
|
||||
#include "windows.h"
|
||||
#include "vector"
|
||||
#include <tchar.h>
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
void InjectCode(void* address, const std::vector<uint8_t> data);
|
||||
void ApplyPatches();
|
||||
|
||||
const LPCWSTR CONFIG_FILE = L".\\config.ini";
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
ApplyPatches();
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ApplyPatches() {
|
||||
|
||||
const struct { void* Address; std::vector<uint8_t> Data; } patches[] =
|
||||
{
|
||||
// Always return true for the SelCredit enter SelPv check
|
||||
{ (void*)0x0000000140393610, { 0xB0, 0x01, 0xC3, 0x90, 0x90, 0x90 } },
|
||||
// Just completely ignore all SYSTEM_STARTUP errors
|
||||
{ (void*)0x00000001403F5080, { 0xC3 } },
|
||||
// Always exit TASK_MODE_APP_ERROR on the first frame
|
||||
{ (void*)0x00000001403F73A7, { 0x90, 0x90 } },
|
||||
{ (void*)0x00000001403F73C3, { 0x89, 0xD1, 0x90 } },
|
||||
// Ignore the EngineClear variable to clear the framebuffer at all resolutions
|
||||
{ (void*)0x0000000140501480, { 0x90, 0x90 } },
|
||||
{ (void*)0x0000000140501515, { 0x90, 0x90 } },
|
||||
// Don't update the touch slider state so we can write our own
|
||||
{ (void*)0x000000014061579B, { 0x90, 0x90, 0x90, 0x8B, 0x42, 0xE0, 0x90, 0x90, 0x90 } },
|
||||
// Write ram files to the current directory instead of Y : / SBZV / ram
|
||||
{ (void*)0x000000014066CF09, { 0xE9, 0xD8, 0x00 } },
|
||||
// Change mdata path from "C:/Mount/Option" to "mdata/"
|
||||
{ (void*)0x0000000140A8CA18, { 0x6D, 0x64, 0x61, 0x74, 0x61, 0x2F, 0x00 } },
|
||||
{ (void*)0x000000014066CEAE, { 0x06 } },
|
||||
// Skip parts of the network check state
|
||||
{ (void*)0x00000001406717B1, { 0xE9, 0x22, 0x03, 0x00 } },
|
||||
// Set the initial DHCP WAIT timer value to 0
|
||||
{ (void*)0x00000001406724E7, { 0x00, 0x00 } },
|
||||
// Ignore SYSTEM_STARTUP Location Server checks
|
||||
{ (void*)0x00000001406732A2, { 0x90, 0x90 } },
|
||||
// Toon Shader Fix by lybxlpsv
|
||||
{ (void*)0x000000014050214F, { 0x90 } },
|
||||
{ (void*)0x0000000140502150, { 0x90 } },
|
||||
// Toon Shader Outline Fix by lybxlpsv
|
||||
{ (void*)0x0000000140641102, { 0x01 } },
|
||||
// Disables call to glutFitWindowSizeToDesktop, prevents window automatic resize
|
||||
{ (void*)0x0000000140194E06, { 0x90, 0x90, 0x90, 0x90, 0x90 } },
|
||||
// Allow modifier mode selection (by Team Shimapan)
|
||||
{ (void*)0x00000001405CB1B3, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 } },
|
||||
{ (void*)0x00000001405CA0F5, { 0x90, 0x90 } },
|
||||
// allow modifier modes to work without use_card
|
||||
{ (void*)0x00000001405CB14A,{ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 } },
|
||||
{ (void*)0x0000000140136CFA,{ 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 } },
|
||||
// enable module selector without use_card (Modules are not getting saved upon selection, commented until a fix is found)
|
||||
//{ (void*)0x00000001405C513B, { 0x01 } },
|
||||
// Show Freeplay instead
|
||||
{ (void*)0x00000001403BABEA, { 0x75 } },
|
||||
// Force Hide IDs
|
||||
{ (void*)0x00000001409A5918, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ (void*)0x00000001409A5928, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
|
||||
};
|
||||
printf("[Patches] Patches loaded\n");
|
||||
|
||||
for (size_t i = 0; i < _countof(patches); i++)
|
||||
InjectCode(patches[i].Address, patches[i].Data);
|
||||
|
||||
auto nCursor = GetPrivateProfileIntW(L"patches", L"cursor", TRUE, CONFIG_FILE);
|
||||
auto nHideFreeplay = GetPrivateProfileIntW(L"patches", L"hide_freeplay", FALSE, CONFIG_FILE);
|
||||
auto nStatusIcons = GetPrivateProfileIntW(L"patches", L"status_icons", 0, CONFIG_FILE);
|
||||
auto nHidePVWatermark = GetPrivateProfileIntW(L"patches", L"hide_pv_watermark", FALSE, CONFIG_FILE);
|
||||
auto nNoPVUi = GetPrivateProfileIntW(L"patches", L"no_pv_ui", FALSE, CONFIG_FILE);
|
||||
auto nHideVolCtrl = GetPrivateProfileIntW(L"patches", L"hide_volume", FALSE, CONFIG_FILE);
|
||||
auto nNoLyrics = GetPrivateProfileIntW(L"patches", L"no_lyrics", FALSE, CONFIG_FILE);
|
||||
auto nNoMovies = GetPrivateProfileIntW(L"patches", L"no_movies", FALSE, CONFIG_FILE);
|
||||
auto nNoError = GetPrivateProfileIntW(L"patches", L"no_error", FALSE, CONFIG_FILE);
|
||||
// Hides the Freeplay text
|
||||
if (nHideFreeplay)
|
||||
{
|
||||
InjectCode((void*)0x00000001403BABEF, { 0x06, 0xB6 });
|
||||
printf("[Patches] Hide Freeplay enabled\n");
|
||||
}
|
||||
// Use GLUT_CURSOR_RIGHT_ARROW instead of GLUT_CURSOR_NONE
|
||||
if (nCursor)
|
||||
{
|
||||
InjectCode((void*)0x000000014019341B, { 0x00 });
|
||||
printf("[Patches] Cursor enabled\n");
|
||||
}
|
||||
// Override status icon states to be invalid (hides them)
|
||||
if (nStatusIcons > 0)
|
||||
{
|
||||
std::vector<uint8_t> cardIcon = { 0xFD, 0x0A };
|
||||
std::vector<uint8_t> networkIcon = { 0x9E, 0x1E };
|
||||
|
||||
if (nStatusIcons == 2) // 2 for error icons
|
||||
{
|
||||
cardIcon = { 0xFA, 0x0A };
|
||||
networkIcon = { 0x9F, 0x1E };
|
||||
printf("[Patches] Status icons set to error state\n");
|
||||
}
|
||||
else if (nStatusIcons == 3) // 3 for OK icons
|
||||
{
|
||||
cardIcon = { 0xFC, 0x0A };
|
||||
networkIcon = { 0xA0, 0x1E };
|
||||
printf("[Patches] Status icons set to OK state\n");
|
||||
}
|
||||
else if (nStatusIcons == 4) // 4 for partial OK icons
|
||||
{
|
||||
cardIcon = { 0xFB, 0x0A };
|
||||
networkIcon = { 0xA1, 0x1E };
|
||||
printf("[Patches] Status icons set to partial OK state\n");
|
||||
}
|
||||
else // 1 or invalid for hidden
|
||||
{
|
||||
cardIcon = { 0xFD, 0x0A };
|
||||
networkIcon = { 0x9E, 0x1E };
|
||||
printf("[Patches] Status icons hidden\n");
|
||||
}
|
||||
|
||||
// card icon
|
||||
InjectCode((void*)0x00000001403B9D6E, cardIcon); // error state
|
||||
InjectCode((void*)0x00000001403B9D73, cardIcon); // OK state
|
||||
|
||||
// network icon
|
||||
InjectCode((void*)0x00000001403BA14B, networkIcon); // error state
|
||||
InjectCode((void*)0x00000001403BA155, networkIcon); // OK state
|
||||
InjectCode((void*)0x00000001403BA16B, networkIcon); // partial state
|
||||
|
||||
InjectCode((void*)0x00000001403BA1A5, { 0x48, 0xE9 }); // never show the error code for partial connection
|
||||
|
||||
// I was going to use this with a string, but the assignment wasn't behaving well and making separate prints was easier than figuring it out
|
||||
// printf("[Patches] Status icons %s\n", iconType);
|
||||
}
|
||||
// Removes PV watermark
|
||||
if (nHidePVWatermark)
|
||||
{
|
||||
InjectCode((void*)0x0000000140A13A88, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
|
||||
printf("[Patches] PV watermark hidden\n");
|
||||
}
|
||||
// Disable the PV screen photo UI
|
||||
if (nNoPVUi)
|
||||
{
|
||||
InjectCode((void*)0x000000014048FA91, { 0xEB, 0x6F }); // skip button panel image (JMP 0x14048FB02)
|
||||
|
||||
// patch minimum PV UI state to 1 instead of 0
|
||||
// hook check for lyrics enabled (UI state < 2) to change UI state 0 into 1
|
||||
// dump new code in the skipped button panel condition
|
||||
InjectCode((void*)0x000000014048FA93, { 0xC7, 0x83, 0x58, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }); // MOV dword ptr [0x158 + RBX],0x1
|
||||
InjectCode((void*)0x000000014048FA9D, { 0xC6, 0x80, 0x3A, 0xD1, 0x02, 0x00, 0x01 }); // MOV byte ptr [0x2d13a + RAX],0x1
|
||||
InjectCode((void*)0x000000014048FAA4, { 0xE9, 0x8B, 0xFB, 0xFF, 0xFF }); // JMP 0x14048F634
|
||||
|
||||
InjectCode((void*)0x000000014048F62D, { 0xE9, 0x61, 0x04, 0x00, 0x00 }); // JMP 0x14048FA93
|
||||
|
||||
printf("[Patches] PV UI disabled\n");
|
||||
}
|
||||
// Don't show volume control
|
||||
if (nHideVolCtrl)
|
||||
{
|
||||
// skip SE button
|
||||
InjectCode((void*)0x00000001409A4D60, { 0xC0, 0xD3 });
|
||||
|
||||
// skip volume sliders button
|
||||
InjectCode((void*)0x0000000140A85F10, { 0xE0, 0x50 });
|
||||
|
||||
printf("[Patches] Volume control hidden\n");
|
||||
}
|
||||
// Skip loading (and therefore displaying) song lyrics
|
||||
if (nNoLyrics)
|
||||
{
|
||||
InjectCode((void*)0x00000001404E7A25, { 0x00, 0x00 });
|
||||
InjectCode((void*)0x00000001404E7950, { 0x48, 0xE9 }); // ensure first iteration doesn't run
|
||||
printf("[Patches] Lyrics disabled\n");
|
||||
}
|
||||
// Skip loading (and therefore displaying) song movies
|
||||
if (nNoMovies)
|
||||
{
|
||||
InjectCode((void*)0x00000001404EB584, { 0x48, 0xE9 });
|
||||
InjectCode((void*)0x00000001404EB471, { 0x48, 0xE9 });
|
||||
printf("[Patches] Movies disabled\n");
|
||||
}
|
||||
// Disable error banner
|
||||
if (nNoError)
|
||||
{
|
||||
// Disable Errors Banner
|
||||
InjectCode((void*)0x00000001403B9E9B, { 0x90, 0x90 });
|
||||
printf("[Patches] Errors Banner disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
void InjectCode(void* address, const std::vector<uint8_t> data)
|
||||
{
|
||||
const size_t byteCount = data.size() * sizeof(uint8_t);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
memcpy(address, data.data(), byteCount);
|
||||
VirtualProtect(address, byteCount, oldProtect, nullptr);
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" 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>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{89F87459-768F-4638-9267-0F90CD74452D}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Render</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;RENDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\freeglut\include;..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;RENDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;RENDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>
|
||||
</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>..\..\..\dependencies\freeglut\include;..\..\..\dependencies\detours\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;..\..\..\dependencies\freeglut\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;RENDER_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?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>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,80 @@
|
||||
#include "framework.h"
|
||||
#include <detours.h>
|
||||
#pragma comment(lib, "detours.lib")
|
||||
#include <GL\freeglut.h>
|
||||
#include <GL\GL.h>
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
|
||||
int hookedCreateWindow(const char* title, void(__cdecl* exit_function)(int))
|
||||
{
|
||||
if (nDisplay == 1)
|
||||
{
|
||||
*fullScreenFlag = 0;
|
||||
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_BORDERLESS);
|
||||
glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH), glutGet(GLUT_SCREEN_HEIGHT));
|
||||
glutInitWindowPosition(0, 0);
|
||||
glutCreateWindow(title);
|
||||
printf("[Render Manager] Borderless mode.\n");
|
||||
}
|
||||
else if (nDisplay == 2)
|
||||
{
|
||||
// Crashes, no idea why yet
|
||||
if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
|
||||
char GameModeString[24];
|
||||
sprintf_s(GameModeString, sizeof(GameModeString),"%dx%d:%d@%d", nWidth, nHeight, nBitDepth ,nRefreshRate);
|
||||
printf("[Render Manager] Game Mode supported and enabled in replacement of Fullscreen.\n");
|
||||
printf(GameModeString);
|
||||
printf("\n");
|
||||
glutGameModeString(GameModeString);
|
||||
glutEnterGameMode();
|
||||
}
|
||||
else {
|
||||
*fullScreenFlag = 1;
|
||||
glutCreateWindow(title);
|
||||
printf("[Render Manager] Fullscreen enabled.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*fullScreenFlag = 0;
|
||||
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
glutInitWindowSize(nWidth, nHeight);
|
||||
glutInitWindowPosition((glutGet(GLUT_SCREEN_WIDTH) - nWidth) / 2, (glutGet(GLUT_SCREEN_HEIGHT) - nHeight) / 2); // Center to the middle of the screen when windowed
|
||||
glutCreateWindow(title);
|
||||
printf("[Render Manager] Windowed mode.\n");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
__int64 hookedParseParameters(int a1, __int64* a2)
|
||||
{
|
||||
// Force -wqhd if Custom Internal Resolution is enabled
|
||||
if (nIntRes)
|
||||
*resolutionType = 15;
|
||||
// Return to the original function
|
||||
return divaParseParameters(a1, a2);
|
||||
}
|
||||
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)divaCreateWindow, hookedCreateWindow);
|
||||
DetourTransactionCommit();
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
DetourAttach(&(PVOID&)divaParseParameters, hookedParseParameters);
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
// Windows Header Files
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
static int(__cdecl* divaCreateWindow)(const char* title, void(__cdecl* exitfunc)(int)) = (int(__cdecl*)(const char* title, void(__cdecl * exitfunc)(int)))0x140194D00;
|
||||
__int64 (__fastcall* divaParseParameters)(int a1, __int64* a2) = (__int64(__fastcall*)(int a1, __int64* a2))0x140193630;
|
||||
|
||||
uint8_t* fullScreenFlag = (uint8_t*)0x140EDA5D1;
|
||||
DWORD* resolutionType = (DWORD*)0x140EDA5D4;
|
||||
|
||||
using namespace std;
|
||||
|
||||
wstring DirPath() {
|
||||
WCHAR buffer[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
||||
wstring::size_type pos = wstring(buffer).find_last_of(L"\\/");
|
||||
return wstring(buffer).substr(0, pos);
|
||||
}
|
||||
|
||||
wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\config.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
|
||||
int nDisplay = GetPrivateProfileIntW(L"resolution", L"display", 0, CONFIG_FILE);
|
||||
int nWidth = GetPrivateProfileIntW(L"resolution", L"width", 1280, CONFIG_FILE);
|
||||
int nHeight = GetPrivateProfileIntW(L"resolution", L"height", 720, CONFIG_FILE);
|
||||
|
||||
int nIntRes = GetPrivateProfileIntW(L"resolution", L"r.enable", FALSE, CONFIG_FILE);
|
||||
int nIntResWidth = GetPrivateProfileIntW(L"resolution", L"r.width", 1280, CONFIG_FILE);
|
||||
int nIntResHeight = GetPrivateProfileIntW(L"resolution", L"r.height", 720, CONFIG_FILE);
|
||||
|
||||
int nBitDepth = GetPrivateProfileIntW(L"resolution", L"bitdepth", 32, CONFIG_FILE);
|
||||
int nRefreshRate = GetPrivateProfileIntW(L"resolution", L"refreshrate", 60, CONFIG_FILE);
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
#include "CameraController.h"
|
||||
#include <algorithm>
|
||||
#include "Input/InputState.h"
|
||||
#include "ComponentsManager.h"
|
||||
#include "../framework.h"
|
||||
#include "../Input/Mouse/Mouse.h"
|
||||
#include "../Input/Keyboard/Keyboard.h"
|
||||
#include "../Input/Bindings/KeyboardBinding.h"
|
||||
|
||||
#define GLUT_CURSOR_RIGHT_ARROW 0x0000
|
||||
#define GLUT_CURSOR_NONE 0x0065
|
||||
|
||||
using namespace TLAC::Input;
|
||||
using namespace TLAC::Utilities;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
CameraController::CameraController()
|
||||
{
|
||||
}
|
||||
|
||||
CameraController::~CameraController()
|
||||
{
|
||||
delete ToggleBinding;
|
||||
|
||||
delete ForwardBinding;
|
||||
delete BackwardBinding;
|
||||
delete LeftBinding;
|
||||
delete RightBinding;
|
||||
|
||||
delete UpBinding;
|
||||
delete DownBinding;
|
||||
delete ClockwiseBinding;
|
||||
delete CounterClockwiseBinding;
|
||||
delete ZoomInBinding;
|
||||
delete ZoomOutBinding;
|
||||
|
||||
delete FastBinding;
|
||||
delete SlowBinding;
|
||||
}
|
||||
|
||||
const char* CameraController::GetDisplayName()
|
||||
{
|
||||
return "camera_controller";
|
||||
}
|
||||
|
||||
void CameraController::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
|
||||
printf("[TLAC] CameraController::Initialize(): Initialized\n");
|
||||
|
||||
for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)cameraSetterAddresses[i], sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
originalSetterBytes[i] = *(uint8_t*)cameraSetterAddresses[i];
|
||||
}
|
||||
|
||||
ToggleBinding = new Binding();
|
||||
ToggleBinding->AddBinding(new KeyboardBinding(VK_F3));
|
||||
|
||||
ForwardBinding = new Binding();
|
||||
ForwardBinding->AddBinding(new KeyboardBinding('W'));
|
||||
BackwardBinding = new Binding();
|
||||
BackwardBinding->AddBinding(new KeyboardBinding('S'));
|
||||
LeftBinding = new Binding();
|
||||
LeftBinding->AddBinding(new KeyboardBinding('A'));
|
||||
RightBinding = new Binding();
|
||||
RightBinding->AddBinding(new KeyboardBinding('D'));
|
||||
|
||||
UpBinding = new Binding();
|
||||
UpBinding->AddBinding(new KeyboardBinding(VK_SPACE));
|
||||
DownBinding = new Binding();
|
||||
DownBinding->AddBinding(new KeyboardBinding(VK_CONTROL));
|
||||
|
||||
ClockwiseBinding = new Binding();
|
||||
ClockwiseBinding->AddBinding(new KeyboardBinding('E'));
|
||||
CounterClockwiseBinding = new Binding();
|
||||
CounterClockwiseBinding->AddBinding(new KeyboardBinding('Q'));
|
||||
|
||||
ZoomInBinding = new Binding();
|
||||
ZoomInBinding->AddBinding(new KeyboardBinding('R'));
|
||||
ZoomOutBinding = new Binding();
|
||||
ZoomOutBinding->AddBinding(new KeyboardBinding('F'));
|
||||
|
||||
FastBinding = new Binding();
|
||||
FastBinding->AddBinding(new KeyboardBinding(VK_SHIFT));
|
||||
SlowBinding = new Binding();
|
||||
SlowBinding->AddBinding(new KeyboardBinding(VK_MENU));
|
||||
|
||||
camera = (Camera*)CAMERA_ADDRESS;
|
||||
}
|
||||
|
||||
void CameraController::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void CameraController::UpdateInput()
|
||||
{
|
||||
if (ToggleBinding->AnyTapped())
|
||||
{
|
||||
SetControls(!GetIsEnabled());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetIsEnabled())
|
||||
return;
|
||||
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
auto mouse = Mouse::GetInstance();
|
||||
|
||||
bool forward = ForwardBinding->AnyDown();
|
||||
bool backward = BackwardBinding->AnyDown();
|
||||
bool left = LeftBinding->AnyDown();
|
||||
bool right = RightBinding->AnyDown();
|
||||
|
||||
bool up = UpBinding->AnyDown();
|
||||
bool down = DownBinding->AnyDown();
|
||||
|
||||
bool fast = FastBinding->AnyDown();
|
||||
bool slow = SlowBinding->AnyDown();
|
||||
|
||||
bool clockwise = ClockwiseBinding->AnyDown();
|
||||
bool counterclockwise = CounterClockwiseBinding->AnyDown();
|
||||
|
||||
bool zoomin = ZoomInBinding->AnyDown();
|
||||
bool zoomout = ZoomOutBinding->AnyDown();
|
||||
|
||||
float speed = GetElapsedTime() * (fast ? fastSpeed : slow ? slowSpeed : normalSpeed);
|
||||
|
||||
if (forward ^ backward)
|
||||
camera->Position += PointFromAngle(verticalRotation + (forward ? +0.0f : -180.0f), speed);
|
||||
|
||||
if (left ^ right)
|
||||
camera->Position += PointFromAngle(verticalRotation + (right ? +90.0f : -90.0f), speed);
|
||||
|
||||
if (up ^ down)
|
||||
camera->Position.Y += speed * (up ? +0.25f : -0.25f);
|
||||
|
||||
if (clockwise ^ counterclockwise)
|
||||
camera->Rotation += speed * (clockwise ? -1.0f : +1.0f);
|
||||
|
||||
if (zoomin ^ zoomout)
|
||||
{
|
||||
camera->HorizontalFov += speed * (zoomin ? -1.0f : +1.0f);
|
||||
camera->HorizontalFov = std::clamp(camera->HorizontalFov, +1.0f, +170.0f);
|
||||
}
|
||||
|
||||
if (mouse->HasMoved())
|
||||
{
|
||||
SetMouseWindowCenter();
|
||||
|
||||
auto delta = mouse->GetDeltaPosition();
|
||||
|
||||
verticalRotation += delta.x * sensitivity;
|
||||
horizontalRotation -= delta.y * (sensitivity / 5.0f);
|
||||
|
||||
horizontalRotation = std::clamp(horizontalRotation, -75.0f, +75.0f);
|
||||
}
|
||||
|
||||
((InputState*)*(uint64_t*)INPUT_STATE_PTR_ADDRESS)->HideCursor();
|
||||
|
||||
Vec2 focus = PointFromAngle(verticalRotation, 1.0f);
|
||||
camera->Focus.X = camera->Position.X + focus.X;
|
||||
camera->Focus.Z = camera->Position.Z + focus.Y;
|
||||
|
||||
camera->Focus.Y = camera->Position.Y + PointFromAngle(horizontalRotation, 5.0f).X;
|
||||
}
|
||||
|
||||
void CameraController::SetControls(bool value)
|
||||
{
|
||||
if (GetIsEnabled() == value)
|
||||
return;
|
||||
|
||||
SetIsEnabled(value);
|
||||
componentsManager->SetUpdateGameInput(!value);
|
||||
|
||||
printf("[TLAC] CameraController::SetControls(): enabled = %s\n", GetIsEnabled() ? "true" : "false");
|
||||
|
||||
typedef void __stdcall _glutSetCursor(int);
|
||||
auto glutSetCursor = (_glutSetCursor*)GLUT_SET_CURSOR_ADDRESS;
|
||||
|
||||
// hide cursor
|
||||
glutSetCursor(value ? GLUT_CURSOR_NONE : GLUT_CURSOR_RIGHT_ARROW);
|
||||
|
||||
if (value)
|
||||
{
|
||||
// disable camera setters
|
||||
for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
|
||||
*(uint8_t*)cameraSetterAddresses[i] = RET_OPCODE;
|
||||
|
||||
// set initial camera angle
|
||||
Vec2 camXz = Vec2(camera->Position.X, camera->Position.Z);
|
||||
Vec2 focusXz = Vec2(camera->Focus.X, camera->Focus.Z);
|
||||
verticalRotation = AngleFromPoints(camXz, focusXz);
|
||||
|
||||
horizontalRotation = 0;
|
||||
camera->Rotation = defaultRotation;
|
||||
camera->HorizontalFov = defaultFov;
|
||||
}
|
||||
else
|
||||
{
|
||||
// restore camera setters
|
||||
for (int i = 0; i < sizeof(cameraSetterAddresses) / sizeof(void*); i++)
|
||||
*(uint8_t*)cameraSetterAddresses[i] = originalSetterBytes[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CameraController::SetMouseWindowCenter()
|
||||
{
|
||||
RECT windowRect = framework::GetWindowBounds();
|
||||
|
||||
int centerX = windowRect.left + (windowRect.right - windowRect.left) / 2;
|
||||
int centerY = windowRect.top + (windowRect.bottom - windowRect.top) / 2;
|
||||
|
||||
Mouse::GetInstance()->SetPosition(centerX, centerY);
|
||||
}
|
||||
|
||||
bool CameraController::GetIsEnabled()
|
||||
{
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
void CameraController::SetIsEnabled(bool value)
|
||||
{
|
||||
isEnabled = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "../Constants.h"
|
||||
#include "../Input/Bindings/Binding.h"
|
||||
#include "../Utilities/Math.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct Camera
|
||||
{
|
||||
Utilities::Vec3 Position;
|
||||
Utilities::Vec3 Focus;
|
||||
float Rotation;
|
||||
float HorizontalFov;
|
||||
float VerticalFov;
|
||||
};
|
||||
|
||||
class CameraController : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
Input::Binding* ToggleBinding;
|
||||
|
||||
Input::Binding* ForwardBinding;
|
||||
Input::Binding* BackwardBinding;
|
||||
Input::Binding* LeftBinding;
|
||||
Input::Binding* RightBinding;
|
||||
|
||||
Input::Binding* UpBinding;
|
||||
Input::Binding* DownBinding;
|
||||
Input::Binding* FastBinding;
|
||||
Input::Binding* SlowBinding;
|
||||
|
||||
Input::Binding* ClockwiseBinding;
|
||||
Input::Binding* CounterClockwiseBinding;
|
||||
|
||||
Input::Binding* ZoomInBinding;
|
||||
Input::Binding* ZoomOutBinding;
|
||||
|
||||
CameraController();
|
||||
~CameraController();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
void SetControls(bool value);
|
||||
|
||||
bool GetIsEnabled();
|
||||
|
||||
private:
|
||||
const float fastSpeed = 0.1f;
|
||||
const float slowSpeed = 0.0005f;
|
||||
const float normalSpeed = 0.005f;
|
||||
|
||||
const float defaultRotation = 0.0f;
|
||||
const float defaultFov = 70.0f;
|
||||
const float sensitivity = 0.25f;
|
||||
|
||||
ComponentsManager* componentsManager;
|
||||
float verticalRotation;
|
||||
float horizontalRotation;
|
||||
|
||||
bool isEnabled;
|
||||
Camera* camera;
|
||||
|
||||
uint8_t originalSetterBytes[4];
|
||||
void* cameraSetterAddresses[4] =
|
||||
{
|
||||
(void*)CAMERA_POS_SETTER_ADDRESS,
|
||||
(void*)CAMERA_INTR_SETTER_ADDRESS,
|
||||
(void*)CAMERA_ROT_SETTER_ADDRESS,
|
||||
(void*)CAMERA_PERS_SETTER_ADDRESS,
|
||||
};
|
||||
|
||||
void SetMouseWindowCenter();
|
||||
void SetIsEnabled(bool value);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
#include "ComponentsManager.h"
|
||||
#include "../FileSystem/ConfigFile.h"
|
||||
#include "../framework.h"
|
||||
#include "Input/InputEmulator.h"
|
||||
#include "Input/TouchSliderEmulator.h"
|
||||
#include "Input/TouchPanelEmulator.h"
|
||||
#include "SysTimer.h"
|
||||
#include "PlayerDataManager.h"
|
||||
#include "FrameRateManager.h"
|
||||
#include "FastLoader.h"
|
||||
#include "StageManager.h"
|
||||
#include "CameraController.h"
|
||||
#include "DebugComponent.h"
|
||||
#include "ScaleComponent.h"
|
||||
#include "FPSLimiter.h"
|
||||
#include "GameTargets/TargetInspector.h"
|
||||
|
||||
using ConfigFile = TLAC::FileSystem::ConfigFile;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
typedef void EngineUpdateInput(void*);
|
||||
|
||||
ComponentsManager::ComponentsManager()
|
||||
{
|
||||
}
|
||||
|
||||
ComponentsManager::~ComponentsManager()
|
||||
{
|
||||
}
|
||||
|
||||
void ComponentsManager::ParseAddComponents()
|
||||
{
|
||||
EmulatorComponent* allComponents[]
|
||||
{
|
||||
new TargetInspector(),
|
||||
new InputEmulator(),
|
||||
new TouchSliderEmulator(),
|
||||
new TouchPanelEmulator(),
|
||||
new SysTimer(),
|
||||
new PlayerDataManager(),
|
||||
new FrameRateManager(),
|
||||
new FastLoader(),
|
||||
new ScaleComponent(),
|
||||
new FPSLimiter(),
|
||||
new StageManager(),
|
||||
new CameraController(),
|
||||
new DebugComponent(),
|
||||
};
|
||||
|
||||
ConfigFile componentsConfig(framework::GetModuleDirectory(), COMPONENTS_CONFIG_FILE_NAME);
|
||||
bool success = componentsConfig.OpenRead();
|
||||
|
||||
if (!success)
|
||||
{
|
||||
printf("ComponentsManager::ParseAddComponents(): Unable to parse %s\n", COMPONENTS_CONFIG_FILE_NAME.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
size_t componentCount = sizeof(allComponents) / sizeof(EmulatorComponent*);
|
||||
components.reserve(componentCount);
|
||||
|
||||
std::string trueString = "true", falseString = "false";
|
||||
|
||||
for (int i = 0; i < componentCount; i++)
|
||||
{
|
||||
std::string* value;
|
||||
|
||||
auto name = allComponents[i]->GetDisplayName();
|
||||
//printf("ComponentsManager::ParseAddComponents(): searching name: %s\n", name);
|
||||
|
||||
if (componentsConfig.TryGetValue(name, &value))
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): %s found\n", name);
|
||||
|
||||
if (*value == trueString)
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): enabling %s...\n", name);
|
||||
components.push_back(allComponents[i]);
|
||||
}
|
||||
else if (*value == falseString)
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): disabling %s...\n", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("ComponentsManager::ParseAddComponents(): invalid value %s for component %s\n", value, name);
|
||||
}
|
||||
|
||||
delete value;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("ParseAddComponents(): component %s not found\n", name);
|
||||
delete allComponents[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ComponentsManager::Initialize()
|
||||
{
|
||||
dwGuiDisplay = (DwGuiDisplay*) * (uint64_t*)DW_GUI_DISPLAY_INSTANCE_PTR_ADDRESS;
|
||||
|
||||
ParseAddComponents();
|
||||
updateStopwatch.Start();
|
||||
|
||||
for (auto& component : components)
|
||||
component->Initialize(this);
|
||||
}
|
||||
|
||||
void ComponentsManager::Update()
|
||||
{
|
||||
elpasedTime = updateStopwatch.Restart();
|
||||
|
||||
for (auto& component : components)
|
||||
{
|
||||
component->SetElapsedTime(elpasedTime);
|
||||
component->Update();
|
||||
}
|
||||
}
|
||||
|
||||
void ComponentsManager::UpdateInput()
|
||||
{
|
||||
if (!GetIsInputEmulatorUsed())
|
||||
{
|
||||
uint64_t* inputStatePtr = (uint64_t*)INPUT_STATE_PTR_ADDRESS;
|
||||
|
||||
// poll input using the original PollInput function we overwrote with the update hook instead
|
||||
if (inputStatePtr != nullptr)
|
||||
((EngineUpdateInput*)ENGINE_UPDATE_INPUT_ADDRESS)((void*)* inputStatePtr);
|
||||
}
|
||||
|
||||
for (auto& component : components)
|
||||
component->UpdateInput();
|
||||
}
|
||||
|
||||
void ComponentsManager::OnFocusGain()
|
||||
{
|
||||
for (auto& component : components)
|
||||
component->OnFocusGain();
|
||||
}
|
||||
|
||||
void ComponentsManager::OnFocusLost()
|
||||
{
|
||||
for (auto& component : components)
|
||||
component->OnFocusLost();
|
||||
}
|
||||
|
||||
void ComponentsManager::Dispose()
|
||||
{
|
||||
for (auto& component : components)
|
||||
delete component;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "../Utilities/Stopwatch.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const std::string COMPONENTS_CONFIG_FILE_NAME = "components.ini";
|
||||
|
||||
// Incomplete type
|
||||
struct DwGuiDisplay
|
||||
{
|
||||
void* vftable;
|
||||
void* active;
|
||||
void* cap;
|
||||
void* on;
|
||||
void* move;
|
||||
void* widget;
|
||||
};
|
||||
|
||||
class ComponentsManager
|
||||
{
|
||||
public:
|
||||
ComponentsManager();
|
||||
~ComponentsManager();
|
||||
void Initialize();
|
||||
void Update();
|
||||
void UpdateInput();
|
||||
void OnFocusGain();
|
||||
void OnFocusLost();
|
||||
void Dispose();
|
||||
|
||||
inline bool GetIsInputEmulatorUsed() { return isInputEmulatorUsed; };
|
||||
inline void SetIsInputEmulatorUsed(bool value) { isInputEmulatorUsed = value; };
|
||||
|
||||
inline bool GetUpdateGameInput() { return updateGameInput; };
|
||||
inline void SetUpdateGameInput(bool value) { updateGameInput = value; }
|
||||
|
||||
inline bool IsDwGuiActive() { return dwGuiDisplay->active != nullptr; };
|
||||
inline bool IsDwGuiHovered() { return dwGuiDisplay->on != nullptr; };
|
||||
|
||||
private:
|
||||
DwGuiDisplay* dwGuiDisplay;
|
||||
|
||||
bool isInputEmulatorUsed = false;
|
||||
bool updateGameInput = true;
|
||||
|
||||
float elpasedTime;
|
||||
Utilities::Stopwatch updateStopwatch;
|
||||
std::vector<EmulatorComponent*> components;
|
||||
|
||||
void ParseAddComponents();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct CustomPlayerData
|
||||
{
|
||||
std::string *PlayerName;
|
||||
std::string* LevelName;
|
||||
int LevelPlateId;
|
||||
int SkinEquip;
|
||||
int BtnSeEquip;
|
||||
int SlideSeEquip;
|
||||
int ChainslideSeEquip;
|
||||
bool ShowGreatClearBorder;
|
||||
bool ShowExcellentClearBorder;
|
||||
bool UseCard;
|
||||
bool GameModifierOptions;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
#include "DebugComponent.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const char* GameStateNames[] =
|
||||
{
|
||||
"STARTUP",
|
||||
"ADVERTISE",
|
||||
"GAME",
|
||||
"DATA_TEST",
|
||||
"TEST_MODE",
|
||||
"APP_ERROR",
|
||||
"MAX",
|
||||
};
|
||||
|
||||
const char* SubGameStateNames[] =
|
||||
{
|
||||
"DATA_INITIALIZE",
|
||||
"SYSTEM_STARTUP",
|
||||
"SYSTEM_STARTUP_ERROR",
|
||||
"WARNING",
|
||||
"LOGO",
|
||||
"RATING",
|
||||
"DEMO",
|
||||
"TITLE",
|
||||
"RANKING",
|
||||
"SCORE_RANKING",
|
||||
"CM",
|
||||
"PHOTO_MODE_DEMO",
|
||||
"SELECTOR",
|
||||
"GAME_MAIN",
|
||||
"GAME_SEL",
|
||||
"STAGE_RESULT",
|
||||
"SCREEN_SHOT_SEL",
|
||||
"SCREEN_SHOT_RESULT",
|
||||
"GAME_OVER",
|
||||
"DATA_TEST_MAIN",
|
||||
"DATA_TEST_MISC",
|
||||
"DATA_TEST_OBJ",
|
||||
"DATA_TEST_STG",
|
||||
"DATA_TEST_MOT",
|
||||
"DATA_TEST_COLLISION",
|
||||
"DATA_TEST_SPR",
|
||||
"DATA_TEST_AET",
|
||||
"DATA_TEST_AUTH_3D",
|
||||
"DATA_TEST_CHR",
|
||||
"DATA_TEST_ITEM",
|
||||
"DATA_TEST_PERF",
|
||||
"DATA_TEST_PVSCRIPT",
|
||||
"DATA_TEST_PRINT",
|
||||
"DATA_TEST_CARD",
|
||||
"DATA_TEST_OPD",
|
||||
"DATA_TEST_SLIDER",
|
||||
"DATA_TEST_GLITTER",
|
||||
"DATA_TEST_GRAPHICS",
|
||||
"DATA_TEST_COLLECTION_CARD",
|
||||
"TEST_MODE_MAIN",
|
||||
"APP_ERROR",
|
||||
"MAX",
|
||||
};
|
||||
|
||||
const char* DataTestNames[] =
|
||||
{
|
||||
"MAIN TEST",
|
||||
"MISC TEST",
|
||||
"OBJECT TEST",
|
||||
"STAGE TEST",
|
||||
"MOTION TEST",
|
||||
"COLLISION TEST",
|
||||
"SPRITE TEST",
|
||||
"2DAUTH TEST",
|
||||
"3DAUTH TEST",
|
||||
"CHARA TEST",
|
||||
"ITEM TEST",
|
||||
"PERFORMANCE TEST",
|
||||
"PVSCRIPT TEST",
|
||||
"PRINT TEST",
|
||||
"CARD TEST",
|
||||
"OPD TEST",
|
||||
"SLIDER TEST",
|
||||
"GLITTER TEST",
|
||||
"GRAPHICS TEST",
|
||||
"COLLECTION CARD TEST",
|
||||
};
|
||||
|
||||
typedef void ChangeGameState(GameState);
|
||||
ChangeGameState* changeGameState = (ChangeGameState*)CHANGE_MODE_ADDRESS;
|
||||
|
||||
typedef void ChangeSubState(GameState, SubGameState);
|
||||
ChangeSubState* changeSubState = (ChangeSubState*)CHANGE_SUB_MODE_ADDRESS;
|
||||
|
||||
DebugComponent::DebugComponent()
|
||||
{
|
||||
}
|
||||
|
||||
DebugComponent::~DebugComponent()
|
||||
{
|
||||
}
|
||||
|
||||
const char* DebugComponent::GetDisplayName()
|
||||
{
|
||||
return "debug_component";
|
||||
}
|
||||
|
||||
void DebugComponent::Initialize(ComponentsManager*)
|
||||
{
|
||||
printf("[TLAC] DebugComponent::Initialize(): Initialized\n");
|
||||
|
||||
InjectPatches();
|
||||
|
||||
HWND consoleHandle = GetConsoleWindow();
|
||||
ShowWindow(consoleHandle, SW_SHOW);
|
||||
|
||||
// In case the FrameRateManager isn't enabled
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)AET_FRAME_DURATION_ADDRESS, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
}
|
||||
|
||||
void DebugComponent::Update()
|
||||
{
|
||||
if (dataTestMain)
|
||||
{
|
||||
Input::Keyboard::GetInstance()->PollInput();
|
||||
UpdateDataTestMain();
|
||||
}
|
||||
}
|
||||
|
||||
void DebugComponent::UpdateInput()
|
||||
{
|
||||
auto keyboard = Input::Keyboard::GetInstance();
|
||||
|
||||
// fast forward menus
|
||||
if (keyboard->IsDown(VK_SHIFT))
|
||||
{
|
||||
float* frameDuration = (float*)AET_FRAME_DURATION_ADDRESS;
|
||||
|
||||
if (keyboard->IsDown(VK_TAB))
|
||||
*frameDuration = 1.0f / (GetGameFrameRate() / aetSpeedUpFactor);
|
||||
else if (keyboard->IsReleased(VK_TAB))
|
||||
*frameDuration = 1.0f / 60.0f;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _countof(gameStateKeyMappings); i++)
|
||||
{
|
||||
if (keyboard->IsTapped(gameStateKeyMappings[i].KeyCode))
|
||||
InternalChangeGameState(gameStateKeyMappings[i].State);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugComponent::InjectPatches()
|
||||
{
|
||||
const struct { void* Address; std::initializer_list<uint8_t> Data; } patches[] =
|
||||
{
|
||||
// Prevent the DATA_TEST game state from exiting on the first frame
|
||||
{ (void*)0x0000000140284B01, { 0x00 } },
|
||||
// Enable dw_gui sprite draw calls
|
||||
{ (void*)0x0000000140192601, { 0x00 } },
|
||||
// Update the dw_gui display
|
||||
{ (void*)0x0000000140302600, { 0xB0, 0x01 } },
|
||||
// Draw the dw_gui display
|
||||
{ (void*)0x0000000140302610, { 0xB0, 0x01 } },
|
||||
// Enable the dw_gui widgets
|
||||
{ (void*)0x0000000140192D00, { 0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3 } },
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < _countof(patches); i++)
|
||||
InjectCode(patches[i].Address, patches[i].Data);
|
||||
}
|
||||
|
||||
void DebugComponent::SetConsoleForeground()
|
||||
{
|
||||
HWND consoleHandle = GetConsoleWindow();
|
||||
ShowWindow(consoleHandle, SW_SHOW);
|
||||
|
||||
if (consoleHandle == NULL)
|
||||
return;
|
||||
|
||||
WINDOWPLACEMENT place = { sizeof(WINDOWPLACEMENT) };
|
||||
GetWindowPlacement(consoleHandle, &place);
|
||||
|
||||
switch (place.showCmd)
|
||||
{
|
||||
case SW_SHOWMAXIMIZED:
|
||||
ShowWindow(consoleHandle, SW_SHOWMAXIMIZED);
|
||||
break;
|
||||
case SW_SHOWMINIMIZED:
|
||||
ShowWindow(consoleHandle, SW_RESTORE);
|
||||
break;
|
||||
default:
|
||||
ShowWindow(consoleHandle, SW_NORMAL);
|
||||
break;
|
||||
}
|
||||
|
||||
SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
|
||||
SetForegroundWindow(consoleHandle);
|
||||
}
|
||||
|
||||
void DebugComponent::PrintDataTestMain()
|
||||
{
|
||||
system("cls");
|
||||
printf(" DATA TEST MAIN:\n\n");
|
||||
|
||||
for (int i = SUB_DATA_TEST_MISC; i <= SUB_DATA_TEST_COLLECTION_CARD; i++)
|
||||
printf("%s %s\n", i == selectionIndex ? "->" : " ", DataTestNames[i - SUB_DATA_TEST_MAIN]);
|
||||
|
||||
printf("\n");
|
||||
SetConsoleForeground();
|
||||
}
|
||||
|
||||
void DebugComponent::InternalChangeGameState(GameState state)
|
||||
{
|
||||
changeGameState(state);
|
||||
printDataTestMain = dataTestMain = (state == GS_DATA_TEST);
|
||||
}
|
||||
|
||||
void DebugComponent::UpdateDataTestMain()
|
||||
{
|
||||
auto keyboard = Input::Keyboard::GetInstance();
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_UP))
|
||||
{
|
||||
selectionIndex--;
|
||||
printDataTestMain = true;
|
||||
}
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_DOWN))
|
||||
{
|
||||
selectionIndex++;
|
||||
printDataTestMain = true;
|
||||
}
|
||||
|
||||
if (selectionIndex > SUB_DATA_TEST_COLLECTION_CARD)
|
||||
selectionIndex = SUB_DATA_TEST_MISC;
|
||||
|
||||
if (selectionIndex < SUB_DATA_TEST_MISC)
|
||||
selectionIndex = SUB_DATA_TEST_COLLECTION_CARD;
|
||||
|
||||
if (keyboard->IsTapped(VK_RETURN))
|
||||
{
|
||||
dataTestMain = false;
|
||||
|
||||
printf("[%s] -> [%s]\n", SubGameStateNames[SUB_DATA_TEST_MAIN], SubGameStateNames[selectionIndex]);
|
||||
changeSubState(GS_DATA_TEST, (SubGameState)selectionIndex);
|
||||
}
|
||||
|
||||
if (printDataTestMain)
|
||||
{
|
||||
PrintDataTestMain();
|
||||
printDataTestMain = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DebugComponent::InjectCode(void* address, const std::initializer_list<uint8_t> &data)
|
||||
{
|
||||
const size_t byteCount = data.size() * sizeof(uint8_t);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
memcpy(address, data.begin(), byteCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "GameState.h"
|
||||
#include "../Input/Keyboard/Keyboard.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class DebugComponent : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
DebugComponent();
|
||||
~DebugComponent();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
private:
|
||||
const float aetSpeedUpFactor = 4.0f;
|
||||
|
||||
bool dataTestMain = false;
|
||||
bool printDataTestMain = false;
|
||||
int selectionIndex = SUB_DATA_TEST_MISC;
|
||||
|
||||
const struct { BYTE KeyCode; GameState State; } gameStateKeyMappings[5] =
|
||||
{
|
||||
{ VK_F4, GS_ADVERTISE },
|
||||
{ VK_F5, GS_GAME },
|
||||
{ VK_F6, GS_DATA_TEST },
|
||||
{ VK_F7, GS_TEST_MODE },
|
||||
{ VK_F8, GS_APP_ERROR },
|
||||
};
|
||||
|
||||
void InjectPatches();
|
||||
void SetConsoleForeground();
|
||||
void PrintDataTestMain();
|
||||
void InternalChangeGameState(GameState state);
|
||||
void UpdateDataTestMain();
|
||||
void InjectCode(void* address, const std::initializer_list<uint8_t> &data);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "EmulatorComponent.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
EmulatorComponent::EmulatorComponent()
|
||||
{
|
||||
}
|
||||
|
||||
EmulatorComponent::~EmulatorComponent()
|
||||
{
|
||||
}
|
||||
|
||||
void EmulatorComponent::SetElapsedTime(float value)
|
||||
{
|
||||
elapsedTime = value;
|
||||
}
|
||||
|
||||
float EmulatorComponent::GetElapsedTime()
|
||||
{
|
||||
return elapsedTime == 0.0f ? (1000.0f / 60.0f) : elapsedTime;
|
||||
}
|
||||
|
||||
float EmulatorComponent::GetFrameRate()
|
||||
{
|
||||
return 1000.0f / GetElapsedTime();
|
||||
}
|
||||
|
||||
float EmulatorComponent::GetGameFrameRate()
|
||||
{
|
||||
return *(float*)FRAME_RATE_ADDRESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class ComponentsManager;
|
||||
|
||||
class EmulatorComponent
|
||||
{
|
||||
public:
|
||||
EmulatorComponent();
|
||||
~EmulatorComponent();
|
||||
|
||||
virtual const char* GetDisplayName() = 0;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) = 0;
|
||||
virtual void Update() = 0;
|
||||
|
||||
virtual void UpdateInput() {};
|
||||
virtual void OnFocusGain() {};
|
||||
virtual void OnFocusLost() {};
|
||||
|
||||
void SetElapsedTime(float value);
|
||||
float GetElapsedTime();
|
||||
float GetFrameRate();
|
||||
float GetGameFrameRate();
|
||||
|
||||
private:
|
||||
float elapsedTime;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "FPSLimiter.h"
|
||||
#include <Windows.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <tchar.h>
|
||||
|
||||
using dsec = std::chrono::duration<double>;
|
||||
using seconds = std::chrono::seconds;
|
||||
|
||||
// this is pretty much just lybxlpsv's limiter, but removed from GLComponent
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
static std::chrono::time_point mBeginFrame = system_clock::now();
|
||||
static std::chrono::time_point prevTimeInSeconds = time_point_cast<seconds>(mBeginFrame);
|
||||
|
||||
const LPCTSTR config_file_name = _T(".\\config.ini");
|
||||
int fpsLimit = GetPrivateProfileIntW(L"graphics", L"fps.limit", 0, config_file_name);
|
||||
|
||||
FPSLimiter::FPSLimiter()
|
||||
{
|
||||
}
|
||||
|
||||
FPSLimiter::~FPSLimiter()
|
||||
{
|
||||
}
|
||||
|
||||
const char* FPSLimiter::GetDisplayName()
|
||||
{
|
||||
return "fps_limiter";
|
||||
}
|
||||
|
||||
void FPSLimiter::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
mBeginFrame = std::chrono::system_clock::now();
|
||||
prevTimeInSeconds = std::chrono::time_point_cast<seconds>(mBeginFrame);
|
||||
frameCountPerSecond = 0;
|
||||
if(fpsLimit != 0)
|
||||
printf("FPSLimiter fpsLimit: %d\n", fpsLimit);
|
||||
}
|
||||
|
||||
// I assume this gets called once per frame... if not this won't work
|
||||
void FPSLimiter::Update()
|
||||
{
|
||||
auto invFpsLimit = round<std::chrono::system_clock::duration>(dsec{ 1. / fpsLimit });
|
||||
auto mEndFrame = mBeginFrame + invFpsLimit;
|
||||
auto timeInSeconds = std::chrono::time_point_cast<seconds>(std::chrono::system_clock::now());
|
||||
|
||||
++frameCountPerSecond;
|
||||
if (timeInSeconds > prevTimeInSeconds)
|
||||
{
|
||||
//printf("FPSLimiter::Update(): FPS: %d\n", frameCountPerSecond);
|
||||
frameCountPerSecond = 0;
|
||||
prevTimeInSeconds = timeInSeconds;
|
||||
}
|
||||
|
||||
// This part keeps the frame rate.
|
||||
if (fpsLimit > 19) // not sure why lyb used 19 here
|
||||
std::this_thread::sleep_until(mEndFrame);
|
||||
mBeginFrame = mEndFrame;
|
||||
mEndFrame = mBeginFrame + invFpsLimit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include <chrono>
|
||||
|
||||
using seconds = std::chrono::seconds;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class FPSLimiter : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
FPSLimiter();
|
||||
~FPSLimiter();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
int frameCountPerSecond;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "FastLoader.h"
|
||||
#include "../Constants.h"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
FastLoader::FastLoader()
|
||||
{
|
||||
}
|
||||
|
||||
FastLoader::~FastLoader()
|
||||
{
|
||||
}
|
||||
|
||||
const char* FastLoader::GetDisplayName()
|
||||
{
|
||||
return "fast_loader";
|
||||
}
|
||||
|
||||
void FastLoader::Initialize(ComponentsManager*)
|
||||
{
|
||||
}
|
||||
|
||||
void FastLoader::Update()
|
||||
{
|
||||
if (dataInitialized)
|
||||
return;
|
||||
|
||||
previousGameState = currentGameState;
|
||||
currentGameState = *(GameState*)CURRENT_GAME_STATE_ADDRESS;
|
||||
|
||||
if (currentGameState == GS_STARTUP)
|
||||
{
|
||||
typedef void UpdateTask();
|
||||
UpdateTask* updateTask = (UpdateTask*)UPDATE_TASKS_ADDRESS;
|
||||
|
||||
// speed up TaskSystemStartup
|
||||
for (int i = 0; i < updatesPerFrame; i++)
|
||||
updateTask();
|
||||
|
||||
constexpr int DATA_INITIALIZED = 3;
|
||||
|
||||
// skip TaskDataInit
|
||||
*(int*)(DATA_INIT_STATE_ADDRESS) = DATA_INITIALIZED;
|
||||
|
||||
// skip TaskWarning
|
||||
*(int*)(SYSTEM_WARNING_ELAPSED_ADDRESS) = 3939;
|
||||
}
|
||||
else if (previousGameState == GS_STARTUP)
|
||||
{
|
||||
dataInitialized = true;
|
||||
printf("[TLAC] FastLoader::Update(): Data Initialized\n");
|
||||
}
|
||||
}
|
||||
|
||||
void FastLoader::UpdateInput()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "GameState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class FastLoader : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
FastLoader();
|
||||
~FastLoader();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
private:
|
||||
const int updatesPerFrame = 39;
|
||||
|
||||
GameState currentGameState;
|
||||
GameState previousGameState;
|
||||
bool dataInitialized = false;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "FrameRateManager.h"
|
||||
#include "../Constants.h"
|
||||
#include "GameState.h"
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
#include "../framework.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
FrameRateManager::FrameRateManager()
|
||||
{
|
||||
}
|
||||
|
||||
FrameRateManager::~FrameRateManager()
|
||||
{
|
||||
}
|
||||
|
||||
const char* FrameRateManager::GetDisplayName()
|
||||
{
|
||||
return "frame_rate_manager";
|
||||
}
|
||||
|
||||
void FrameRateManager::Initialize(ComponentsManager*)
|
||||
{
|
||||
pvFrameRate = (float*)PV_FRAME_RATE_ADDRESS;
|
||||
frameSpeed = (float*)FRAME_SPEED_ADDRESS;
|
||||
aetFrameDuration = (float*)AET_FRAME_DURATION_ADDRESS;
|
||||
|
||||
// The default is expected to be 1.0 / 60.0
|
||||
defaultAetFrameDuration = *aetFrameDuration;
|
||||
|
||||
// This const variable is stored inside a data segment so we don't want to throw any access violations
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)AET_FRAME_DURATION_ADDRESS, sizeof(float), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
}
|
||||
|
||||
void FrameRateManager::Update()
|
||||
{
|
||||
float frameRate = 0.0f;
|
||||
frameRate = RoundFrameRate(GetGameFrameRate());
|
||||
|
||||
*aetFrameDuration = 1.0f / frameRate;
|
||||
*pvFrameRate = frameRate;
|
||||
|
||||
bool inGame = *(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME;
|
||||
|
||||
if (inGame)
|
||||
{
|
||||
// During the GAME state the frame rate will be handled by the PvFrameRate instead
|
||||
|
||||
constexpr float defaultFrameSpeed = 1.0f;
|
||||
constexpr float defaultFrameRate = 60.0f;
|
||||
|
||||
// This PV struct creates a copy of the PvFrameRate & PvFrameSpeed during the loading screen
|
||||
// so we'll make sure to keep updating it as well.
|
||||
// Each new motion also creates its own copy of these values but keeping track of the active motions is annoying
|
||||
// and they usually change multiple times per PV anyway so this should suffice for now
|
||||
float* pvStructPvFrameRate = (float*)(0x0000000140CDD978 + 0x2BF98);
|
||||
float* pvStructPvFrameSpeed = (float*)(0x0000000140CDD978 + 0x2BF9C);
|
||||
|
||||
*pvStructPvFrameRate = *pvFrameRate;
|
||||
*pvStructPvFrameSpeed = (defaultFrameRate / *pvFrameRate);
|
||||
|
||||
*frameSpeed = defaultFrameSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
*frameSpeed = *aetFrameDuration / defaultAetFrameDuration;
|
||||
}
|
||||
}
|
||||
|
||||
float FrameRateManager::RoundFrameRate(float frameRate)
|
||||
{
|
||||
constexpr float roundingThreshold = 4.0f;
|
||||
|
||||
for (int i = 0; i < sizeof(commonRefreshRates) / sizeof(float); i++)
|
||||
{
|
||||
float refreshRate = commonRefreshRates[i];
|
||||
|
||||
if (frameRate > refreshRate - roundingThreshold && frameRate < refreshRate + roundingThreshold)
|
||||
frameRate = refreshRate;
|
||||
}
|
||||
|
||||
return frameRate;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class FrameRateManager : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
FrameRateManager();
|
||||
~FrameRateManager();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
float *pvFrameRate;
|
||||
float *frameSpeed;
|
||||
float *aetFrameDuration;
|
||||
float defaultAetFrameDuration;
|
||||
|
||||
float commonRefreshRates[5]
|
||||
{
|
||||
60.0f,
|
||||
75.0f,
|
||||
120.0f,
|
||||
144.0f,
|
||||
240.0f,
|
||||
};
|
||||
|
||||
float RoundFrameRate(float frameRate);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum GameState : uint32_t
|
||||
{
|
||||
GS_STARTUP,
|
||||
GS_ADVERTISE,
|
||||
GS_GAME,
|
||||
GS_DATA_TEST,
|
||||
GS_TEST_MODE,
|
||||
GS_APP_ERROR,
|
||||
GS_MAX,
|
||||
};
|
||||
|
||||
enum SubGameState : uint32_t
|
||||
{
|
||||
SUB_DATA_INITIALIZE,
|
||||
SUB_SYSTEM_STARTUP,
|
||||
SUB_SYSTEM_STARTUP_ERROR,
|
||||
SUB_WARNING,
|
||||
SUB_LOGO,
|
||||
SUB_RATING,
|
||||
SUB_DEMO,
|
||||
SUB_TITLE,
|
||||
SUB_RANKING,
|
||||
SUB_SCORE_RANKING,
|
||||
SUB_CM,
|
||||
SUB_PHOTO_MODE_DEMO,
|
||||
SUB_SELECTOR,
|
||||
SUB_GAME_MAIN,
|
||||
SUB_GAME_SEL,
|
||||
SUB_STAGE_RESULT,
|
||||
SUB_SCREEN_SHOT_SEL,
|
||||
SUB_SCREEN_SHOT_RESULT,
|
||||
SUB_GAME_OVER,
|
||||
SUB_DATA_TEST_MAIN,
|
||||
SUB_DATA_TEST_MISC,
|
||||
SUB_DATA_TEST_OBJ,
|
||||
SUB_DATA_TEST_STG,
|
||||
SUB_DATA_TEST_MOT,
|
||||
SUB_DATA_TEST_COLLISION,
|
||||
SUB_DATA_TEST_SPR,
|
||||
SUB_DATA_TEST_AET,
|
||||
SUB_DATA_TEST_AUTH_3D,
|
||||
SUB_DATA_TEST_CHR,
|
||||
SUB_DATA_TEST_ITEM,
|
||||
SUB_DATA_TEST_PERF,
|
||||
SUB_DATA_TEST_PVSCRIPT,
|
||||
SUB_DATA_TEST_PRINT,
|
||||
SUB_DATA_TEST_CARD,
|
||||
SUB_DATA_TEST_OPD,
|
||||
SUB_DATA_TEST_SLIDER,
|
||||
SUB_DATA_TEST_GLITTER,
|
||||
SUB_DATA_TEST_GRAPHICS,
|
||||
SUB_DATA_TEST_COLLECTION_CARD,
|
||||
SUB_TEST_MODE_MAIN,
|
||||
SUB_APP_ERROR,
|
||||
SUB_MAX,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum HoldState
|
||||
{
|
||||
HOLD_NONE,
|
||||
HOLD_SANKAKU = 64,
|
||||
HOLD_MARU = 128,
|
||||
HOLD_BATSU = 256,
|
||||
HOLD_SHIKAKU = 512,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum TargetHitStates
|
||||
{
|
||||
COOL,
|
||||
FINE,
|
||||
SAFE,
|
||||
SAD,
|
||||
COOL_WRONG, // unsure
|
||||
FINE_WRONG, // unsure
|
||||
SAFE_WRONG, // unsure
|
||||
SAD_WRONG, // unsure
|
||||
WORST,
|
||||
NONE = 21,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "TargetInspector.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
bool TargetInspector::repressTbl[maxTargetSlots];
|
||||
|
||||
TargetInspector::TargetInspector()
|
||||
{
|
||||
}
|
||||
|
||||
TargetInspector::~TargetInspector()
|
||||
{
|
||||
}
|
||||
|
||||
void TargetInspector::Initialize(ComponentsManager*)
|
||||
{
|
||||
tgtTypePtr = (int*)TGT_TYPE_BASE_ADDRESS;
|
||||
tgtHitStatePtr = (int*)TGT_HIT_STATE_BASE_ADDRESS;
|
||||
tgtRemainingTimePtr = (float*)TGT_REMAINING_DURATION_BASE_ADDRESS;
|
||||
}
|
||||
|
||||
void TargetInspector::Update()
|
||||
{
|
||||
GetTargetStates();
|
||||
UpdateRepressTbl();
|
||||
}
|
||||
|
||||
const char* TargetInspector::GetDisplayName()
|
||||
{
|
||||
return "target_inspector";
|
||||
}
|
||||
|
||||
void TargetInspector::GetTargetStates()
|
||||
{
|
||||
for (int i = 0; i < maxTargetSlots; ++i)
|
||||
{
|
||||
tgtStates[i].tgtType = *((int*)((char*)tgtTypePtr + (i * offset)));
|
||||
tgtStates[i].tgtHitState = *((int*)((char*)tgtHitStatePtr + (i * offset)));
|
||||
tgtStates[i].tgtRemainingTime = *((float*)((char*)tgtRemainingTimePtr + (i * offset)));
|
||||
}
|
||||
}
|
||||
|
||||
void TargetInspector::UpdateRepressTbl()
|
||||
{
|
||||
for (int i = 0; i < maxTargetSlots; ++i)
|
||||
{
|
||||
repressTbl[i] = IsWithinRange(tgtStates[i].tgtRemainingTime)
|
||||
&& HasNotBeenHit(tgtStates[i].tgtHitState)
|
||||
&& !IsSlide(tgtStates[i].tgtType);
|
||||
}
|
||||
}
|
||||
|
||||
bool TargetInspector::IsWithinRange(float time)
|
||||
{
|
||||
return time < timingThreshold && time > -timingThreshold && time != 0;
|
||||
}
|
||||
|
||||
bool TargetInspector::HasNotBeenHit(int hitState)
|
||||
{
|
||||
return hitState == NONE;
|
||||
}
|
||||
|
||||
bool TargetInspector::IsSlide(int type)
|
||||
{
|
||||
return (type >= SLIDE_L && type <= SLIDE_LONG_R) || type >= SLIDE_L_CH;
|
||||
}
|
||||
|
||||
bool TargetInspector::IsAnyRepress()
|
||||
{
|
||||
for (int i = 0; i < maxTargetSlots; ++i)
|
||||
{
|
||||
if (repressTbl[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "../Input/InputEmulator.h"
|
||||
#include "../../Constants.h"
|
||||
#include "TargetHitStates.h"
|
||||
#include "TargetState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const int maxTargetSlots = 32;
|
||||
|
||||
class TargetInspector : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
TargetInspector();
|
||||
~TargetInspector();
|
||||
|
||||
static bool repressTbl[maxTargetSlots];
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
void GetTargetStates();
|
||||
static bool IsAnyRepress();
|
||||
|
||||
private:
|
||||
const uint64_t offset = 0x4A8;
|
||||
const float timingThreshold = 0.13f; // PS4 estimate
|
||||
|
||||
TargetState tgtStates[maxTargetSlots];
|
||||
|
||||
int* tgtTypePtr;
|
||||
int* tgtHitStatePtr;
|
||||
float* tgtRemainingTimePtr;
|
||||
|
||||
bool IsSlide(int);
|
||||
bool IsWithinRange(float);
|
||||
bool HasNotBeenHit(int);
|
||||
void UpdateRepressTbl();
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TargetState
|
||||
{
|
||||
int tgtType;
|
||||
int tgtHitState;
|
||||
float tgtRemainingTime;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum TargetTypes
|
||||
{
|
||||
SANKAKU,
|
||||
MARU,
|
||||
BATSU,
|
||||
SHIKAKU,
|
||||
SANKAKU_H,
|
||||
MARU_H,
|
||||
BATSU_H,
|
||||
SHIKAKU_H,
|
||||
SLIDE_L = 12,
|
||||
SLIDE_R,
|
||||
SLIDE_LONG_L = 15,
|
||||
SLIDE_LONG_R,
|
||||
SANKAKU_CH = 18,
|
||||
MARU_CH,
|
||||
BATSU_CH,
|
||||
SHIKAKU_CH,
|
||||
SLIDE_L_CH = 23,
|
||||
SLIDE_R_CH,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum InputBufferType
|
||||
{
|
||||
InputBufferType_Tapped,
|
||||
InputBufferType_Released,
|
||||
InputBufferType_Down,
|
||||
InputBufferType_DoubleTapped,
|
||||
InputBufferType_IntervalTapped,
|
||||
InputBufferType_Max,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
#include <iostream>
|
||||
#include "windows.h"
|
||||
#include "InputEmulator.h"
|
||||
#include "../ComponentsManager.h"
|
||||
#include "../../Constants.h"
|
||||
#include "../../framework.h"
|
||||
#include "../../Input/Bindings/KeyboardBinding.h"
|
||||
#include "../../Input/Bindings/XinputBinding.h"
|
||||
#include "../../Input/Bindings/MouseBinding.h"
|
||||
#include "../../Input/Bindings/Ds4Binding.h"
|
||||
#include "../../Input/KeyConfig/Config.h"
|
||||
#include "../../Utilities/Operations.h"
|
||||
#include "../../Utilities/EnumBitwiseOperations.h"
|
||||
#include "../../FileSystem/ConfigFile.h"
|
||||
|
||||
const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
|
||||
|
||||
using namespace TLAC::Input;
|
||||
using namespace TLAC::Input::KeyConfig;
|
||||
using namespace TLAC::Utilities;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
|
||||
InputEmulator::InputEmulator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
InputEmulator::~InputEmulator()
|
||||
{
|
||||
delete TestBinding;
|
||||
delete ServiceBinding;
|
||||
|
||||
delete StartBinding;
|
||||
delete SankakuBinding;
|
||||
delete ShikakuBinding;
|
||||
delete BatsuBinding;
|
||||
delete MaruBinding;
|
||||
|
||||
delete LeftBinding;
|
||||
delete RightBinding;
|
||||
}
|
||||
|
||||
const char* InputEmulator::GetDisplayName()
|
||||
{
|
||||
return "input_emulator";
|
||||
}
|
||||
|
||||
void InputEmulator::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
componentsManager->SetIsInputEmulatorUsed(true);
|
||||
|
||||
inputState = GetInputStatePtr((void*)INPUT_STATE_PTR_ADDRESS);
|
||||
inputState->HideCursor();
|
||||
|
||||
TestBinding = new Binding();
|
||||
ServiceBinding = new Binding();
|
||||
StartBinding = new Binding();
|
||||
|
||||
SankakuBinding = new Binding();
|
||||
ShikakuBinding = new Binding();
|
||||
BatsuBinding = new Binding();
|
||||
MaruBinding = new Binding();
|
||||
|
||||
LeftBinding = new Binding();
|
||||
RightBinding = new Binding();
|
||||
|
||||
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
|
||||
configFile.OpenRead();
|
||||
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_TEST", *TestBinding, { "F1" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_SERVICE", *ServiceBinding, { "F2" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_START", *StartBinding, { "Enter" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_TRIANGLE", *SankakuBinding, { "W", "I" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_SQUARE", *ShikakuBinding, { "A", "J" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_CROSS", *BatsuBinding, { "S", "K" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_CIRCLE", *MaruBinding, { "D", "L" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_LEFT", *LeftBinding, { "Q", "U" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "JVS_RIGHT", *RightBinding, { "E", "O" });
|
||||
|
||||
mouseScrollPvSelection = configFile.GetBooleanValue("mouse_scroll_pv_selection");
|
||||
}
|
||||
|
||||
void InputEmulator::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void InputEmulator::OnFocusLost()
|
||||
{
|
||||
// to prevent buttons from being "stuck"
|
||||
inputState->ClearState();
|
||||
inputState->HideCursor();
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateInput()
|
||||
{
|
||||
if (!componentsManager->GetUpdateGameInput())
|
||||
return;
|
||||
|
||||
if (!componentsManager->IsDwGuiActive())
|
||||
{
|
||||
UpdateJvsInput();
|
||||
|
||||
if (mouseScrollPvSelection && !componentsManager->IsDwGuiHovered())
|
||||
UpdateMousePvScroll();
|
||||
}
|
||||
|
||||
UpdateDwGuiInput();
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateJvsInput()
|
||||
{
|
||||
auto tappedFunc = [](void* binding) { return ((Binding*)binding)->AnyTapped(); };
|
||||
auto releasedFunc = [](void* binding) { return ((Binding*)binding)->AnyReleased(); };
|
||||
auto downFunc = [](void* binding) { return ((Binding*)binding)->AnyDown(); };
|
||||
|
||||
lastDownState = inputState->Down.Buttons;
|
||||
|
||||
inputState->Tapped.Buttons = GetJvsButtonsState(tappedFunc);
|
||||
inputState->Released.Buttons = GetJvsButtonsState(releasedFunc);
|
||||
inputState->Down.Buttons = GetJvsButtonsState(downFunc);
|
||||
inputState->DoubleTapped.Buttons = GetJvsButtonsState(tappedFunc);
|
||||
inputState->IntervalTapped.Buttons = GetJvsButtonsState(tappedFunc);
|
||||
|
||||
UpdateHoldState();
|
||||
heldButtons = GetButtonFromHold();
|
||||
|
||||
if ((lastDownState &= inputState->Tapped.Buttons) != 0)
|
||||
{
|
||||
inputState->Down.Buttons ^= inputState->Tapped.Buttons;
|
||||
if (IsHold() && !TargetInspector::IsAnyRepress())
|
||||
inputState->Down.Buttons |= heldButtons;
|
||||
}
|
||||
|
||||
// repress held down buttons to not block input
|
||||
//inputState->Down.Buttons ^= inputState->Tapped.Buttons;
|
||||
}
|
||||
|
||||
HoldState InputEmulator::GetHoldState()
|
||||
{
|
||||
return (HoldState) * ((int*)HOLD_STATE_ADDRESS);
|
||||
}
|
||||
|
||||
int InputEmulator::GetMaxHoldState()
|
||||
{
|
||||
return *(int*)MAX_HOLD_STATE_ADDRESS;
|
||||
}
|
||||
|
||||
bool InputEmulator::IsHold()
|
||||
{
|
||||
return ((holdState != HOLD_NONE) && (GetMaxHoldState() != 1));
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateHoldState()
|
||||
{
|
||||
holdState = GetHoldState();
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
int holdId = 1 << (i + 6);
|
||||
|
||||
if ((holdId & holdState) != 0)
|
||||
holdTbl[i] = 1;
|
||||
else
|
||||
holdTbl[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateDwGuiInput()
|
||||
{
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
auto mouse = Mouse::GetInstance();
|
||||
|
||||
auto pos = mouse->GetRelativePosition();
|
||||
inputState->MouseX = (int)pos.x;
|
||||
inputState->MouseY = (int)pos.y;
|
||||
|
||||
auto deltaPos = mouse->GetDeltaPosition();
|
||||
inputState->MouseDeltaX = (int)deltaPos.x;
|
||||
inputState->MouseDeltaY = (int)deltaPos.y;
|
||||
|
||||
inputState->Key = GetKeyState();
|
||||
|
||||
for (int i = 0; i < sizeof(keyBits) / sizeof(KeyBit); i++)
|
||||
UpdateInputBit(keyBits[i].Bit, keyBits[i].KeyCode);
|
||||
|
||||
for (int i = InputBufferType_Tapped; i < InputBufferType_Max; i++)
|
||||
{
|
||||
inputState->SetBit(scrollUpBit, mouse->GetIsScrolledUp(), (InputBufferType)i);
|
||||
inputState->SetBit(scrollDownBit, mouse->GetIsScrolledDown(), (InputBufferType)i);
|
||||
}
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateMousePvScroll()
|
||||
{
|
||||
// I originally wanted to use a MouseBinding set to JVS_LEFT / JVS_RIGHT
|
||||
// but that ended up being too slow because a PV slot can only be scrolled to once the scroll animation has finished playing
|
||||
int* slotsToScroll = (int*)PV_SEL_SLOTS_TO_SCROLL;
|
||||
int* modulesToScroll = (int*)MODULE_SEL_SLOTS_TO_SCROLL;
|
||||
|
||||
auto mouse = Mouse::GetInstance();
|
||||
if (mouse->GetIsScrolledUp())
|
||||
{
|
||||
if (*(int*)PV_SEL_SLOTS_CONST < 26) *slotsToScroll -= 1;
|
||||
if (*(int*)MODULE_IS_RECOMMENDED == 0) *modulesToScroll -= 1;
|
||||
}
|
||||
if (mouse->GetIsScrolledDown())
|
||||
{
|
||||
if (*(int*)PV_SEL_SLOTS_CONST < 26) *slotsToScroll += 1;
|
||||
if (*(int*)MODULE_IS_RECOMMENDED == 0) *modulesToScroll += 1;
|
||||
}
|
||||
}
|
||||
|
||||
InputState* InputEmulator::GetInputStatePtr(void* address)
|
||||
{
|
||||
return (InputState*)(*(uint64_t*)address);
|
||||
}
|
||||
|
||||
JvsButtons InputEmulator::GetJvsButtonsState(bool(*buttonTestFunc)(void*))
|
||||
{
|
||||
JvsButtons buttons = JVS_NONE;
|
||||
|
||||
if (buttonTestFunc(TestBinding))
|
||||
buttons |= JVS_TEST;
|
||||
if (buttonTestFunc(ServiceBinding))
|
||||
buttons |= JVS_SERVICE;
|
||||
|
||||
if (buttonTestFunc(StartBinding))
|
||||
buttons |= JVS_START;
|
||||
|
||||
if (buttonTestFunc(SankakuBinding))
|
||||
buttons |= JVS_TRIANGLE;
|
||||
if (buttonTestFunc(ShikakuBinding))
|
||||
buttons |= JVS_SQUARE;
|
||||
if (buttonTestFunc(BatsuBinding))
|
||||
buttons |= JVS_CROSS;
|
||||
if (buttonTestFunc(MaruBinding))
|
||||
buttons |= JVS_CIRCLE;
|
||||
|
||||
if (buttonTestFunc(LeftBinding))
|
||||
buttons |= JVS_L;
|
||||
if (buttonTestFunc(RightBinding))
|
||||
buttons |= JVS_R;
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
JvsButtons InputEmulator::GetButtonFromHold()
|
||||
{
|
||||
JvsButtons buttons = JVS_NONE;
|
||||
|
||||
if (holdTbl[0])
|
||||
buttons |= JVS_TRIANGLE;
|
||||
if (holdTbl[1])
|
||||
buttons |= JVS_CIRCLE;
|
||||
if (holdTbl[2])
|
||||
buttons |= JVS_CROSS;
|
||||
if (holdTbl[3])
|
||||
buttons |= JVS_SQUARE;
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
char InputEmulator::GetKeyState()
|
||||
{
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
|
||||
bool upper = keyboard->IsDown(VK_SHIFT);
|
||||
constexpr char caseDifference = 'A' - 'a';
|
||||
|
||||
char inputKey = 0x00;
|
||||
|
||||
for (char key = '0'; key < 'Z'; key++)
|
||||
{
|
||||
if (keyboard->IsIntervalTapped(key))
|
||||
inputKey = (upper || key < 'A') ? key : (key - caseDifference);
|
||||
}
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_BACK))
|
||||
inputKey = 0x08;
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_TAB))
|
||||
inputKey = 0x09;
|
||||
|
||||
if (keyboard->IsIntervalTapped(VK_SPACE))
|
||||
inputKey = 0x20;
|
||||
|
||||
return inputKey;
|
||||
}
|
||||
|
||||
void InputEmulator::UpdateInputBit(uint32_t bit, uint8_t keycode)
|
||||
{
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
|
||||
inputState->SetBit(bit, keyboard->IsTapped(keycode), InputBufferType_Tapped);
|
||||
inputState->SetBit(bit, keyboard->IsReleased(keycode), InputBufferType_Released);
|
||||
inputState->SetBit(bit, keyboard->IsDown(keycode), InputBufferType_Down);
|
||||
inputState->SetBit(bit, keyboard->IsDoubleTapped(keycode), InputBufferType_DoubleTapped);
|
||||
inputState->SetBit(bit, keyboard->IsIntervalTapped(keycode), InputBufferType_IntervalTapped);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include <functional>
|
||||
#include <Windows.h>
|
||||
#include "InputState.h"
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "../../Input/Bindings/Binding.h"
|
||||
#include "../GameTargets/TargetTypes.h"
|
||||
#include "../GameTargets/TargetHitStates.h"
|
||||
#include "../GameTargets/HoldState.h"
|
||||
#include "../GameTargets/TargetInspector.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct KeyBit
|
||||
{
|
||||
uint32_t Bit;
|
||||
uint8_t KeyCode;
|
||||
};
|
||||
|
||||
class InputEmulator : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
Input::Binding* TestBinding;
|
||||
Input::Binding* ServiceBinding;
|
||||
|
||||
Input::Binding* StartBinding;
|
||||
Input::Binding* SankakuBinding;
|
||||
Input::Binding* ShikakuBinding;
|
||||
Input::Binding* BatsuBinding;
|
||||
Input::Binding* MaruBinding;
|
||||
|
||||
Input::Binding* LeftBinding;
|
||||
Input::Binding* RightBinding;
|
||||
|
||||
InputEmulator();
|
||||
~InputEmulator();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
virtual void OnFocusLost() override;
|
||||
|
||||
private:
|
||||
ComponentsManager* componentsManager;
|
||||
|
||||
bool mouseScrollPvSelection = false;
|
||||
const uint32_t scrollUpBit = 99;
|
||||
const uint32_t scrollDownBit = 100;
|
||||
|
||||
KeyBit keyBits[20] =
|
||||
{
|
||||
{ 5, VK_LEFT },
|
||||
{ 6, VK_RIGHT },
|
||||
|
||||
{ 29, VK_SPACE },
|
||||
{ 39, 'A' },
|
||||
{ 43, 'E' },
|
||||
{ 42, 'D' },
|
||||
{ 55, 'Q' },
|
||||
{ 57, 'S' }, // unsure
|
||||
{ 61, 'W' },
|
||||
{ 63, 'Y' },
|
||||
{ 84, 'L' }, // unsure
|
||||
|
||||
{ 80, VK_RETURN },
|
||||
{ 81, VK_SHIFT },
|
||||
{ 82, VK_CONTROL },
|
||||
{ 83, VK_MENU },
|
||||
|
||||
{ 91, VK_UP },
|
||||
{ 93, VK_DOWN },
|
||||
|
||||
{ 96, MK_LBUTTON },
|
||||
{ 97, VK_MBUTTON },
|
||||
{ 98, MK_RBUTTON },
|
||||
};
|
||||
|
||||
InputState* inputState;
|
||||
JvsButtons lastDownState;
|
||||
JvsButtons heldButtons;
|
||||
|
||||
int holdTbl[4];
|
||||
HoldState holdState;
|
||||
|
||||
void UpdateJvsInput();
|
||||
void UpdateDwGuiInput();
|
||||
void UpdateMousePvScroll();
|
||||
void UpdateHoldState();
|
||||
InputState* GetInputStatePtr(void* address);
|
||||
JvsButtons GetJvsButtonsState(bool(*buttonTestFunc)(void*));
|
||||
JvsButtons GetButtonFromHold();
|
||||
char GetKeyState();
|
||||
HoldState GetHoldState();
|
||||
int GetMaxHoldState();
|
||||
bool IsHold();
|
||||
|
||||
void UpdateInputBit(uint32_t bit, uint8_t keycode);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#include "InputState.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
void InputState::ClearState()
|
||||
{
|
||||
memset(this, 0, sizeof(InputState));
|
||||
}
|
||||
|
||||
void InputState::HideCursor()
|
||||
{
|
||||
MouseX = INT32_MIN;
|
||||
MouseY = INT32_MIN;
|
||||
MouseDeltaX = 0;
|
||||
MouseDeltaY = 0;
|
||||
}
|
||||
|
||||
void InputState::SetBit(uint32_t bit, bool value, InputBufferType inputType)
|
||||
{
|
||||
uint8_t* data = GetInputBuffer(inputType);
|
||||
|
||||
if (data == nullptr || bit < 0 || bit >= MAX_BUTTON_BIT)
|
||||
return;
|
||||
|
||||
int byteIndex = (bit / 8);
|
||||
int bitIndex = (bit % 8);
|
||||
|
||||
BYTE mask = (1 << bitIndex);
|
||||
|
||||
data[byteIndex] = value ? (data[byteIndex] | mask) : (data[byteIndex] & ~mask);
|
||||
}
|
||||
|
||||
uint8_t* InputState::GetInputBuffer(InputBufferType inputType)
|
||||
{
|
||||
switch (inputType)
|
||||
{
|
||||
case InputBufferType_Tapped:
|
||||
return (uint8_t*)&Tapped;
|
||||
|
||||
case InputBufferType_Released:
|
||||
return (uint8_t*)&Released;
|
||||
|
||||
case InputBufferType_Down:
|
||||
return (uint8_t*)&Down;
|
||||
|
||||
case InputBufferType_DoubleTapped:
|
||||
return (uint8_t*)&DoubleTapped;
|
||||
|
||||
case InputBufferType_IntervalTapped:
|
||||
return (uint8_t*)&IntervalTapped;
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "JvsButtons.h"
|
||||
#include "InputBufferType.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const int MAX_BUTTON_BIT = 0x6F;
|
||||
|
||||
// The button state is larger than the size of a register
|
||||
// but only the first 32 bits are used during normal gameplay
|
||||
// so this will provide the convenience of still being able to access them through a bit field
|
||||
union ButtonState
|
||||
{
|
||||
JvsButtons Buttons;
|
||||
uint32_t State[4];
|
||||
};
|
||||
|
||||
// total sizeof() == 0x20E0
|
||||
struct InputState
|
||||
{
|
||||
ButtonState Tapped;
|
||||
ButtonState Released;
|
||||
|
||||
ButtonState Down;
|
||||
uint32_t Padding_20[4];
|
||||
|
||||
ButtonState DoubleTapped;
|
||||
uint32_t Padding_30[4];
|
||||
|
||||
ButtonState IntervalTapped;
|
||||
uint32_t Padding_38[12];
|
||||
|
||||
int32_t MouseX;
|
||||
int32_t MouseY;
|
||||
int32_t MouseDeltaX;
|
||||
int32_t MouseDeltaY;
|
||||
|
||||
uint32_t Padding_AC[8];
|
||||
uint8_t Padding_D0[3];
|
||||
char Key;
|
||||
|
||||
void ClearState();
|
||||
void HideCursor();
|
||||
void SetBit(uint32_t bit, bool value, InputBufferType inputType);
|
||||
uint8_t* GetInputBuffer(InputBufferType inputType);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
enum JvsButtons : uint32_t
|
||||
{
|
||||
JVS_NONE = 0 << 0x00, // 0x0
|
||||
|
||||
JVS_TEST = 1 << 0x00, // 0x1
|
||||
JVS_SERVICE = 1 << 0x01, // 0x2
|
||||
|
||||
JVS_START = 1 << 0x02, // 0x4
|
||||
JVS_TRIANGLE = 1 << 0x07, // 0x80
|
||||
JVS_SQUARE = 1 << 0x08, // 0x100
|
||||
JVS_CROSS = 1 << 0x09, // 0x200
|
||||
JVS_CIRCLE = 1 << 0x0A, // 0x400
|
||||
JVS_L = 1 << 0x0B, // 0x800
|
||||
JVS_R = 1 << 0x0C, // 0x1000
|
||||
|
||||
JVS_SW1 = 1 << 0x12, // 0x40000
|
||||
JVS_SW2 = 1 << 0x13, // 0x80000
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "TouchPanelEmulator.h"
|
||||
#include <iostream>
|
||||
#include "../ComponentsManager.h"
|
||||
#include "../../Constants.h"
|
||||
#include "../../Input/Mouse/Mouse.h"
|
||||
#include "../../Input/Keyboard/Keyboard.h"
|
||||
|
||||
using namespace TLAC::Input;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
TouchPanelEmulator::TouchPanelEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
TouchPanelEmulator::~TouchPanelEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
const char* TouchPanelEmulator::GetDisplayName()
|
||||
{
|
||||
return "touch_panel_emulator";
|
||||
}
|
||||
|
||||
void TouchPanelEmulator::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
state = GetTouchStatePtr((void*)TASK_TOUCH_ADDRESS);
|
||||
}
|
||||
|
||||
void TouchPanelEmulator::Update()
|
||||
{
|
||||
state->ConnectionState = 1;
|
||||
}
|
||||
|
||||
void TouchPanelEmulator::UpdateInput()
|
||||
{
|
||||
if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || componentsManager->IsDwGuiHovered())
|
||||
return;
|
||||
|
||||
// TODO: rescale TouchReaction aet position
|
||||
auto keyboard = Keyboard::GetInstance();
|
||||
auto pos = Mouse::GetInstance()->GetRelativePosition();
|
||||
|
||||
state->XPosition = (float)pos.x;
|
||||
state->YPosition = (float)pos.y;
|
||||
|
||||
bool down = keyboard->IsDown(VK_LBUTTON);
|
||||
bool released = keyboard->IsReleased(VK_LBUTTON);
|
||||
|
||||
state->ContactType = (down ? 0x2 : released ? 0x1 : 0x0);
|
||||
state->Pressure = (float)(state->ContactType != 0);
|
||||
}
|
||||
|
||||
TouchPanelState* TouchPanelEmulator::GetTouchStatePtr(void *address)
|
||||
{
|
||||
return (TouchPanelState*)address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "TouchPanelState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class TouchPanelEmulator : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
TouchPanelEmulator();
|
||||
~TouchPanelEmulator();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
private:
|
||||
ComponentsManager* componentsManager;
|
||||
|
||||
TouchPanelState* state;
|
||||
TouchPanelState* GetTouchStatePtr(void *address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TouchPanelState
|
||||
{
|
||||
int Padding00[0x1E];
|
||||
int ConnectionState;
|
||||
int Padding01[0x06];
|
||||
float XPosition;
|
||||
float YPosition;
|
||||
float Pressure;
|
||||
int ContactType;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
#include "TouchSliderEmulator.h"
|
||||
#include "../ComponentsManager.h"
|
||||
#include "../../Constants.h"
|
||||
#include "../../framework.h"
|
||||
#include "../../Input/Mouse/Mouse.h"
|
||||
#include "../../Input/Keyboard/Keyboard.h"
|
||||
#include "../../Input/Bindings/KeyboardBinding.h"
|
||||
#include "../../Input/KeyConfig/Config.h"
|
||||
#include "../../FileSystem/ConfigFile.h"
|
||||
#include "../../Utilities/Math.h"
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
using namespace TLAC::Input;
|
||||
using namespace TLAC::Input::KeyConfig;
|
||||
using namespace TLAC::Utilities;
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
|
||||
|
||||
TouchSliderEmulator::TouchSliderEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
TouchSliderEmulator::~TouchSliderEmulator()
|
||||
{
|
||||
delete LeftSideSlideLeft;
|
||||
delete LeftSideSlideRight;
|
||||
|
||||
delete RightSideSlideLeft;
|
||||
delete RightSideSlideRight;
|
||||
}
|
||||
|
||||
const char* TouchSliderEmulator::GetDisplayName()
|
||||
{
|
||||
return "touch_slider_emulator";
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::Initialize(ComponentsManager* manager)
|
||||
{
|
||||
componentsManager = manager;
|
||||
sliderState = (TouchSliderState*)SLIDER_CTRL_TASK_ADDRESS;
|
||||
|
||||
LeftSideSlideLeft = new Binding();
|
||||
LeftSideSlideRight = new Binding();
|
||||
|
||||
RightSideSlideLeft = new Binding();
|
||||
RightSideSlideRight = new Binding();
|
||||
|
||||
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
|
||||
configFile.OpenRead();
|
||||
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
|
||||
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" });
|
||||
Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" });
|
||||
|
||||
float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed");
|
||||
|
||||
if (touchSliderEmulationSpeed != 0.0f)
|
||||
sliderSpeed = touchSliderEmulationSpeed;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::Update()
|
||||
{
|
||||
sliderState->State = SLIDER_OK;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::UpdateInput()
|
||||
{
|
||||
if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive())
|
||||
return;
|
||||
|
||||
sliderIncrement = GetElapsedTime() / sliderSpeed;
|
||||
|
||||
constexpr float sensorStep = (1.0f / SLIDER_SENSORS);
|
||||
|
||||
EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f);
|
||||
EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep);
|
||||
|
||||
sliderState->ResetSensors();
|
||||
|
||||
for (int i = 0; i < CONTACT_POINTS; i++)
|
||||
ApplyContactPoint(ContactPoints[i], i);
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::OnFocusLost()
|
||||
{
|
||||
sliderState->ResetSensors();
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::EmulateSliderInput(Binding *leftBinding, Binding *rightBinding, ContactPoint &contactPoint, float start, float end)
|
||||
{
|
||||
bool leftDown = leftBinding->AnyDown();
|
||||
bool rightDown = rightBinding->AnyDown();
|
||||
|
||||
if (leftDown)
|
||||
contactPoint.Position -= sliderIncrement;
|
||||
else if (rightDown)
|
||||
contactPoint.Position += sliderIncrement;
|
||||
|
||||
if (contactPoint.Position < start)
|
||||
contactPoint.Position = end;
|
||||
|
||||
if (contactPoint.Position > end)
|
||||
contactPoint.Position = start;
|
||||
|
||||
bool leftTapped = leftBinding->AnyTapped();
|
||||
bool rightTapped = rightBinding->AnyTapped();
|
||||
|
||||
if (leftTapped || rightTapped)
|
||||
contactPoint.Position = (start + end) / 2.0f;
|
||||
|
||||
contactPoint.InContact = leftDown || rightDown;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::ApplyContactPoint(ContactPoint &contactPoint, int section)
|
||||
{
|
||||
sliderState->SectionTouched[section] = contactPoint.InContact;
|
||||
|
||||
int pressure = contactPoint.InContact ? FULL_PRESSURE : NO_PRESSURE;
|
||||
float position = std::clamp(contactPoint.Position, 0.0f, 1.0f);
|
||||
|
||||
if (contactPoint.InContact)
|
||||
{
|
||||
int sensor = (int)(position * (SLIDER_SENSORS - 1));
|
||||
|
||||
sliderState->SetSensor(sensor, pressure);
|
||||
}
|
||||
|
||||
constexpr float startRange = -1.0f;
|
||||
constexpr float endRange = +1.0f;
|
||||
|
||||
sliderState->SectionPositions[section] = contactPoint.InContact ? (ConvertRange(0.0f, 1.0f, startRange, endRange, position)) : 0.0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "../EmulatorComponent.h"
|
||||
#include "TouchSliderState.h"
|
||||
#include "../../Input/Bindings/Binding.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
constexpr int SLIDER_INPUTS = 4;
|
||||
constexpr int CONTACT_POINTS = 2;
|
||||
|
||||
struct ContactPoint
|
||||
{
|
||||
float Position;
|
||||
bool InContact;
|
||||
};
|
||||
|
||||
class TouchSliderEmulator : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
Input::Binding* LeftSideSlideLeft;
|
||||
Input::Binding* LeftSideSlideRight;
|
||||
|
||||
Input::Binding* RightSideSlideLeft;
|
||||
Input::Binding* RightSideSlideRight;
|
||||
|
||||
TouchSliderEmulator();
|
||||
~TouchSliderEmulator();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
virtual void OnFocusLost() override;
|
||||
|
||||
private:
|
||||
ComponentsManager* componentsManager;
|
||||
float sliderSpeed = 750.0f;
|
||||
float sliderIncrement;
|
||||
|
||||
TouchSliderState *sliderState;
|
||||
ContactPoint ContactPoints[CONTACT_POINTS];
|
||||
|
||||
void EmulateSliderInput(Input::Binding *leftBinding, Input::Binding *rightBinding, ContactPoint &contactPoint, float start, float end);
|
||||
void ApplyContactPoint(ContactPoint &contactPoint, int section);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "TouchSliderState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
void TouchSliderState::SetSensor(int index, int value)
|
||||
{
|
||||
if (index < 0 || index >= SLIDER_SENSORS)
|
||||
return;
|
||||
|
||||
SensorPressureLevels[index] = value;
|
||||
SensorTouched[index].IsTouched = value > 0;
|
||||
}
|
||||
|
||||
void TouchSliderState::ResetSensors()
|
||||
{
|
||||
for (int i = 0; i < SLIDER_SENSORS; i++)
|
||||
SetSensor(i, NO_PRESSURE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#define SLIDER_OK 3
|
||||
#define SLIDER_SECTIONS 4
|
||||
#define SLIDER_SENSORS 32
|
||||
|
||||
#define NO_PRESSURE 0
|
||||
#define FULL_PRESSURE 180
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TouchSliderState
|
||||
{
|
||||
uint8_t Padding0000[112];
|
||||
|
||||
int32_t State;
|
||||
|
||||
uint8_t Padding0074[20 + 12];
|
||||
|
||||
int32_t SensorPressureLevels[SLIDER_SENSORS];
|
||||
|
||||
uint8_t Padding0108[52 - 12];
|
||||
|
||||
float SectionPositions[SLIDER_SECTIONS];
|
||||
int SectionConnections[SLIDER_SECTIONS];
|
||||
uint8_t Padding015C[4];
|
||||
bool SectionTouched[SLIDER_SECTIONS];
|
||||
|
||||
uint8_t Padding013C[3128 - 52 - 40];
|
||||
|
||||
struct
|
||||
{
|
||||
uint8_t Padding00[2];
|
||||
bool IsTouched;
|
||||
uint8_t Padding[45];
|
||||
} SensorTouched[SLIDER_SENSORS];
|
||||
|
||||
void SetSensor(int index, int value);
|
||||
void ResetSensors();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,973 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
struct PlayerData
|
||||
{
|
||||
int8_t use_card;
|
||||
int8_t freeplay;
|
||||
int8_t field_2;
|
||||
int8_t field_3;
|
||||
int32_t card_type;
|
||||
int32_t field_8;
|
||||
int32_t field_C;
|
||||
int32_t field_10;
|
||||
int32_t field_14;
|
||||
int32_t field_18;
|
||||
int32_t field_1C;
|
||||
int32_t field_20;
|
||||
int32_t field_24;
|
||||
int32_t field_28;
|
||||
int32_t field_2C;
|
||||
int32_t field_30;
|
||||
int32_t field_34;
|
||||
int32_t field_38;
|
||||
int32_t field_3C;
|
||||
int32_t field_40;
|
||||
int32_t field_44;
|
||||
int32_t field_48;
|
||||
int32_t field_4C;
|
||||
int32_t field_50;
|
||||
int32_t field_54;
|
||||
int32_t field_58;
|
||||
int32_t field_5C;
|
||||
int32_t field_60;
|
||||
int32_t field_64;
|
||||
int32_t field_68;
|
||||
int32_t field_6C;
|
||||
int32_t field_70;
|
||||
int32_t field_74;
|
||||
int32_t field_78;
|
||||
int32_t field_7C;
|
||||
int32_t field_80;
|
||||
int32_t field_84;
|
||||
int32_t field_88;
|
||||
int32_t field_8C;
|
||||
int32_t field_90;
|
||||
int32_t field_94;
|
||||
int32_t field_98;
|
||||
int32_t field_9C;
|
||||
int32_t field_A0;
|
||||
int32_t field_A4;
|
||||
int32_t field_A8;
|
||||
int32_t field_AC;
|
||||
int32_t field_B0;
|
||||
int32_t field_B4;
|
||||
int32_t field_B8;
|
||||
int32_t field_BC;
|
||||
int32_t field_C0;
|
||||
int32_t field_C4;
|
||||
int32_t field_C8;
|
||||
int32_t field_CC;
|
||||
int32_t play_data_id;
|
||||
int32_t accept_index;
|
||||
int32_t start_index;
|
||||
int32_t field_DC;
|
||||
char* player_name;
|
||||
int32_t field_E8;
|
||||
int32_t field_EC;
|
||||
int32_t field_F0;
|
||||
int32_t field_F4;
|
||||
int32_t field_F8;
|
||||
int32_t field_FC;
|
||||
char* level_name;
|
||||
int32_t field_108;
|
||||
int32_t field_10C;
|
||||
int32_t field_110;
|
||||
int32_t field_114;
|
||||
int32_t field_118;
|
||||
int32_t field_11C;
|
||||
int32_t field_120;
|
||||
int32_t level_plate_id;
|
||||
int32_t field_128;
|
||||
int32_t vocaloid_point;
|
||||
int32_t hp_vol;
|
||||
int32_t act_toggle;
|
||||
int32_t act_vol;
|
||||
int32_t act_slide_vol;
|
||||
int32_t field_140;
|
||||
int32_t field_144;
|
||||
int32_t field_148;
|
||||
int32_t field_14C;
|
||||
int32_t field_150;
|
||||
int32_t field_154;
|
||||
int32_t field_158;
|
||||
int32_t field_15C;
|
||||
int32_t field_160;
|
||||
int32_t field_164;
|
||||
int32_t field_168;
|
||||
int32_t field_16C;
|
||||
int32_t field_170;
|
||||
int32_t field_174;
|
||||
int32_t field_178;
|
||||
int32_t field_17C;
|
||||
int32_t field_180;
|
||||
int32_t field_184;
|
||||
int32_t field_188;
|
||||
int32_t field_18C;
|
||||
int32_t field_190;
|
||||
int32_t field_194;
|
||||
int32_t field_198;
|
||||
int32_t field_19C;
|
||||
int32_t field_1A0;
|
||||
int32_t field_1A4;
|
||||
int32_t field_1A8;
|
||||
int32_t field_1AC;
|
||||
int32_t field_1B0;
|
||||
int32_t field_1B4;
|
||||
int32_t field_1B8;
|
||||
int32_t field_1BC;
|
||||
int32_t field_1C0;
|
||||
int32_t field_1C4;
|
||||
int32_t field_1C8;
|
||||
int32_t field_1CC;
|
||||
int32_t field_1D0;
|
||||
int32_t field_1D4;
|
||||
int32_t field_1D8;
|
||||
int32_t field_1DC;
|
||||
int32_t field_1E0;
|
||||
int32_t field_1E4;
|
||||
int32_t field_1E8;
|
||||
int32_t field_1EC;
|
||||
int32_t field_1F0;
|
||||
int32_t field_1F4;
|
||||
int32_t field_1F8;
|
||||
int32_t field_1FC;
|
||||
int32_t field_200;
|
||||
int32_t field_204;
|
||||
int32_t field_208;
|
||||
int32_t field_20C;
|
||||
int32_t field_210;
|
||||
int32_t field_214;
|
||||
int32_t field_218;
|
||||
int32_t field_21C;
|
||||
int32_t field_220;
|
||||
int32_t field_224;
|
||||
int32_t field_228;
|
||||
int32_t field_22C;
|
||||
int32_t field_230;
|
||||
int32_t field_234;
|
||||
int32_t field_238;
|
||||
int32_t field_23C;
|
||||
int32_t field_240;
|
||||
int32_t field_244;
|
||||
int32_t field_248;
|
||||
int32_t field_24C;
|
||||
int32_t field_250;
|
||||
int32_t field_254;
|
||||
int32_t field_258;
|
||||
int32_t field_25C;
|
||||
int32_t field_260;
|
||||
int32_t field_264;
|
||||
int32_t field_268;
|
||||
int32_t field_26C;
|
||||
int32_t field_270;
|
||||
int32_t field_274;
|
||||
int32_t field_278;
|
||||
int32_t field_27C;
|
||||
int32_t field_280;
|
||||
int32_t field_284;
|
||||
int32_t field_288;
|
||||
int32_t field_28C;
|
||||
int32_t field_290;
|
||||
int32_t field_294;
|
||||
int32_t field_298;
|
||||
int32_t field_29C;
|
||||
int32_t field_2A0;
|
||||
int32_t field_2A4;
|
||||
int32_t field_2A8;
|
||||
int32_t field_2AC;
|
||||
int8_t use_pv_module_equip;
|
||||
int8_t ch_pv_module_equip;
|
||||
int8_t field_2B2;
|
||||
int8_t field_2B3;
|
||||
int32_t module_filter_kind;
|
||||
int32_t field_2B8;
|
||||
int32_t field_2BC;
|
||||
int32_t field_2C0;
|
||||
int32_t field_2C4;
|
||||
int32_t field_2C8;
|
||||
int32_t field_2CC;
|
||||
int32_t field_2D0;
|
||||
int32_t field_2D4;
|
||||
int32_t field_2D8;
|
||||
int32_t field_2DC;
|
||||
int32_t field_2E0;
|
||||
int32_t field_2E4;
|
||||
int32_t field_2E8;
|
||||
int32_t field_2EC;
|
||||
int32_t field_2F0;
|
||||
int32_t field_2F4;
|
||||
int32_t field_2F8;
|
||||
int32_t field_2FC;
|
||||
int32_t field_300;
|
||||
int32_t field_304;
|
||||
int32_t field_308;
|
||||
int32_t field_30C;
|
||||
int32_t field_310;
|
||||
int32_t field_314;
|
||||
int32_t field_318;
|
||||
int32_t field_31C;
|
||||
int32_t field_320;
|
||||
int32_t field_324;
|
||||
int32_t field_328;
|
||||
int32_t field_32C;
|
||||
int32_t field_330;
|
||||
int32_t field_334;
|
||||
int32_t field_338;
|
||||
int32_t field_33C;
|
||||
int32_t field_340;
|
||||
int32_t field_344;
|
||||
int32_t field_348;
|
||||
int32_t field_34C;
|
||||
int32_t field_350;
|
||||
int32_t field_354;
|
||||
int32_t field_358;
|
||||
int32_t field_35C;
|
||||
int32_t field_360;
|
||||
int32_t field_364;
|
||||
int32_t field_368;
|
||||
int32_t field_36C;
|
||||
int32_t field_370;
|
||||
int32_t field_374;
|
||||
int32_t field_378;
|
||||
int32_t field_37C;
|
||||
int32_t field_380;
|
||||
int32_t field_384;
|
||||
int32_t field_388;
|
||||
int32_t field_38C;
|
||||
int32_t field_390;
|
||||
int32_t field_394;
|
||||
int32_t field_398;
|
||||
int32_t field_39C;
|
||||
int32_t field_3A0;
|
||||
int32_t field_3A4;
|
||||
int32_t field_3A8;
|
||||
int32_t field_3AC;
|
||||
int32_t field_3B0;
|
||||
int32_t field_3B4;
|
||||
int32_t field_3B8;
|
||||
int32_t field_3BC;
|
||||
int32_t field_3C0;
|
||||
int32_t field_3C4;
|
||||
int32_t field_3C8;
|
||||
int32_t field_3CC;
|
||||
int32_t field_3D0;
|
||||
int32_t field_3D4;
|
||||
int32_t field_3D8;
|
||||
int32_t field_3DC;
|
||||
int32_t field_3E0;
|
||||
int32_t field_3E4;
|
||||
int32_t field_3E8;
|
||||
int32_t field_3EC;
|
||||
int32_t field_3F0;
|
||||
int32_t field_3F4;
|
||||
int32_t field_3F8;
|
||||
int32_t field_3FC;
|
||||
int32_t field_400;
|
||||
int32_t field_404;
|
||||
int32_t field_408;
|
||||
int32_t field_40C;
|
||||
int32_t field_410;
|
||||
int32_t field_414;
|
||||
int32_t field_418;
|
||||
int32_t field_41C;
|
||||
int32_t field_420;
|
||||
int32_t field_424;
|
||||
int32_t field_428;
|
||||
int32_t field_42C;
|
||||
int32_t field_430;
|
||||
int32_t field_434;
|
||||
int32_t field_438;
|
||||
int32_t field_43C;
|
||||
int32_t field_440;
|
||||
int32_t field_444;
|
||||
int32_t field_448;
|
||||
int32_t field_44C;
|
||||
int32_t field_450;
|
||||
int32_t field_454;
|
||||
int32_t field_458;
|
||||
int32_t field_45C;
|
||||
int32_t field_460;
|
||||
int32_t field_464;
|
||||
int32_t field_468;
|
||||
int32_t field_46C;
|
||||
int32_t field_470;
|
||||
int32_t field_474;
|
||||
int32_t field_478;
|
||||
int32_t field_47C;
|
||||
int32_t field_480;
|
||||
int32_t field_484;
|
||||
int32_t field_488;
|
||||
int32_t field_48C;
|
||||
int32_t field_490;
|
||||
int32_t field_494;
|
||||
int32_t field_498;
|
||||
int32_t field_49C;
|
||||
int32_t field_4A0;
|
||||
int32_t field_4A4;
|
||||
int32_t field_4A8;
|
||||
int32_t field_4AC;
|
||||
int32_t field_4B0;
|
||||
int32_t field_4B4;
|
||||
int32_t field_4B8;
|
||||
int32_t field_4BC;
|
||||
int32_t field_4C0;
|
||||
int32_t field_4C4;
|
||||
int32_t field_4C8;
|
||||
int32_t field_4CC;
|
||||
int32_t field_4D0;
|
||||
int32_t field_4D4;
|
||||
int32_t field_4D8;
|
||||
int32_t field_4DC;
|
||||
int32_t field_4E0;
|
||||
int32_t field_4E4;
|
||||
int32_t field_4E8;
|
||||
int32_t field_4EC;
|
||||
int32_t field_4F0;
|
||||
int32_t field_4F4;
|
||||
int32_t field_4F8;
|
||||
int32_t field_4FC;
|
||||
int32_t field_500;
|
||||
int32_t field_504;
|
||||
int32_t field_508;
|
||||
int32_t field_50C;
|
||||
int32_t field_510;
|
||||
int32_t field_514;
|
||||
int32_t field_518;
|
||||
int32_t field_51C;
|
||||
int32_t field_520;
|
||||
int32_t field_524;
|
||||
int32_t field_528;
|
||||
int32_t field_52C;
|
||||
int32_t field_530;
|
||||
int32_t field_534;
|
||||
int32_t field_538;
|
||||
int32_t field_53C;
|
||||
int32_t field_540;
|
||||
int32_t field_544;
|
||||
int32_t skin_equip;
|
||||
int32_t skin_equip_cmn;
|
||||
int32_t use_pv_skin_equip;
|
||||
int32_t btn_se_equip;
|
||||
int32_t btn_se_equip_cmn;
|
||||
int32_t use_pv_btn_se_equip;
|
||||
int32_t slide_se_equip;
|
||||
int32_t slide_se_equip_cmn;
|
||||
int32_t use_pv_slide_se_equip;
|
||||
int32_t chainslide_se_equip;
|
||||
int32_t chainslide_se_equip_cmn;
|
||||
int32_t use_pv_chainslide_se_equip;
|
||||
int32_t slidertouch_se_equip;
|
||||
int32_t slidertouch_se_equip_cmn;
|
||||
int32_t use_pv_slidertouch_se_equip;
|
||||
int32_t field_584;
|
||||
int32_t field_588;
|
||||
int32_t field_58C;
|
||||
int32_t field_590;
|
||||
int32_t field_594;
|
||||
int32_t field_598;
|
||||
int32_t field_59C;
|
||||
int32_t field_5A0;
|
||||
int32_t field_5A4;
|
||||
int32_t field_5A8;
|
||||
int32_t field_5AC;
|
||||
int32_t field_5B0;
|
||||
int32_t field_5B4;
|
||||
int32_t field_5B8;
|
||||
int32_t field_5BC;
|
||||
int32_t field_5C0;
|
||||
int32_t field_5C4;
|
||||
int32_t field_5C8;
|
||||
int32_t field_5CC;
|
||||
int32_t field_5D0;
|
||||
int32_t field_5D4;
|
||||
int32_t field_5D8;
|
||||
int32_t field_5DC;
|
||||
int32_t field_5E0;
|
||||
int32_t field_5E4;
|
||||
int32_t field_5E8;
|
||||
int32_t field_5EC;
|
||||
int32_t field_5F0;
|
||||
int32_t field_5F4;
|
||||
int32_t field_5F8;
|
||||
int32_t field_5FC;
|
||||
int32_t field_600;
|
||||
int32_t field_604;
|
||||
int32_t field_608;
|
||||
int32_t field_60C;
|
||||
int32_t field_610;
|
||||
int32_t field_614;
|
||||
int32_t field_618;
|
||||
int32_t field_61C;
|
||||
int32_t field_620;
|
||||
int32_t field_624;
|
||||
int32_t field_628;
|
||||
int32_t field_62C;
|
||||
int32_t field_630;
|
||||
int32_t field_634;
|
||||
int32_t field_638;
|
||||
int32_t field_63C;
|
||||
int32_t field_640;
|
||||
int32_t field_644;
|
||||
int32_t field_648;
|
||||
int32_t field_64C;
|
||||
int32_t field_650;
|
||||
int32_t field_654;
|
||||
int32_t field_658;
|
||||
int32_t field_65C;
|
||||
int32_t field_660;
|
||||
int32_t field_664;
|
||||
int32_t field_668;
|
||||
int32_t field_66C;
|
||||
int32_t field_670;
|
||||
int32_t field_674;
|
||||
int32_t field_678;
|
||||
int32_t field_67C;
|
||||
int32_t field_680;
|
||||
int32_t field_684;
|
||||
int32_t field_688;
|
||||
int32_t field_68C;
|
||||
int32_t field_690;
|
||||
int32_t field_694;
|
||||
int32_t field_698;
|
||||
int32_t field_69C;
|
||||
int32_t field_6A0;
|
||||
int32_t field_6A4;
|
||||
int32_t field_6A8;
|
||||
int32_t field_6AC;
|
||||
int32_t field_6B0;
|
||||
int32_t field_6B4;
|
||||
int32_t field_6B8;
|
||||
int32_t field_6BC;
|
||||
int32_t field_6C0;
|
||||
int32_t field_6C4;
|
||||
int32_t field_6C8;
|
||||
int32_t field_6CC;
|
||||
int32_t field_6D0;
|
||||
int32_t field_6D4;
|
||||
int32_t field_6D8;
|
||||
int32_t field_6DC;
|
||||
int32_t field_6E0;
|
||||
int32_t field_6E4;
|
||||
int32_t field_6E8;
|
||||
int32_t field_6EC;
|
||||
int32_t field_6F0;
|
||||
int32_t field_6F4;
|
||||
int32_t field_6F8;
|
||||
int32_t field_6FC;
|
||||
int32_t field_700;
|
||||
int32_t field_704;
|
||||
int32_t field_708;
|
||||
int32_t field_70C;
|
||||
int32_t field_710;
|
||||
int32_t field_714;
|
||||
int32_t field_718;
|
||||
int32_t field_71C;
|
||||
int32_t field_720;
|
||||
int32_t field_724;
|
||||
int32_t field_728;
|
||||
int32_t field_72C;
|
||||
int32_t field_730;
|
||||
int32_t field_734;
|
||||
int32_t field_738;
|
||||
int32_t field_73C;
|
||||
int32_t field_740;
|
||||
int32_t field_744;
|
||||
int32_t field_748;
|
||||
int32_t field_74C;
|
||||
int32_t field_750;
|
||||
int32_t field_754;
|
||||
int32_t field_758;
|
||||
int32_t field_75C;
|
||||
int32_t field_760;
|
||||
int32_t field_764;
|
||||
int32_t field_768;
|
||||
int32_t field_76C;
|
||||
int32_t field_770;
|
||||
int32_t field_774;
|
||||
int32_t field_778;
|
||||
int32_t field_77C;
|
||||
int32_t field_780;
|
||||
int32_t field_784;
|
||||
int32_t field_788;
|
||||
int32_t field_78C;
|
||||
int32_t field_790;
|
||||
int32_t field_794;
|
||||
int32_t field_798;
|
||||
int32_t field_79C;
|
||||
int32_t field_7A0;
|
||||
int32_t field_7A4;
|
||||
int32_t field_7A8;
|
||||
int32_t field_7AC;
|
||||
int32_t field_7B0;
|
||||
int32_t field_7B4;
|
||||
int32_t field_7B8;
|
||||
int32_t field_7BC;
|
||||
int32_t field_7C0;
|
||||
int32_t field_7C4;
|
||||
int32_t field_7C8;
|
||||
int32_t field_7CC;
|
||||
int32_t field_7D0;
|
||||
int32_t field_7D4;
|
||||
int32_t field_7D8;
|
||||
int32_t field_7DC;
|
||||
int32_t field_7E0;
|
||||
int32_t field_7E4;
|
||||
int32_t field_7E8;
|
||||
int32_t field_7EC;
|
||||
int32_t field_7F0;
|
||||
int32_t field_7F4;
|
||||
int32_t field_7F8;
|
||||
int32_t field_7FC;
|
||||
int32_t field_800;
|
||||
int32_t field_804;
|
||||
int32_t field_808;
|
||||
int32_t field_80C;
|
||||
int32_t field_810;
|
||||
int32_t field_814;
|
||||
int32_t field_818;
|
||||
int32_t field_81C;
|
||||
int32_t field_820;
|
||||
int32_t field_824;
|
||||
int32_t field_828;
|
||||
int32_t field_82C;
|
||||
int32_t field_830;
|
||||
int32_t field_834;
|
||||
int32_t field_838;
|
||||
int32_t field_83C;
|
||||
int32_t field_840;
|
||||
int32_t field_844;
|
||||
int32_t field_848;
|
||||
int32_t field_84C;
|
||||
int32_t field_850;
|
||||
int32_t field_854;
|
||||
int32_t field_858;
|
||||
int32_t field_85C;
|
||||
int32_t field_860;
|
||||
int32_t field_864;
|
||||
int32_t field_868;
|
||||
int32_t field_86C;
|
||||
int32_t field_870;
|
||||
int32_t field_874;
|
||||
int32_t field_878;
|
||||
int32_t field_87C;
|
||||
int32_t field_880;
|
||||
int32_t field_884;
|
||||
int32_t field_888;
|
||||
int32_t field_88C;
|
||||
int32_t field_890;
|
||||
int32_t field_894;
|
||||
int32_t field_898;
|
||||
int32_t field_89C;
|
||||
int32_t field_8A0;
|
||||
int32_t field_8A4;
|
||||
int32_t field_8A8;
|
||||
int32_t field_8AC;
|
||||
int32_t field_8B0;
|
||||
int32_t field_8B4;
|
||||
int32_t field_8B8;
|
||||
int32_t field_8BC;
|
||||
int32_t field_8C0;
|
||||
int32_t field_8C4;
|
||||
int32_t field_8C8;
|
||||
int32_t field_8CC;
|
||||
int32_t field_8D0;
|
||||
int32_t field_8D4;
|
||||
int32_t field_8D8;
|
||||
int32_t field_8DC;
|
||||
int32_t field_8E0;
|
||||
int32_t field_8E4;
|
||||
int32_t field_8E8;
|
||||
int32_t field_8EC;
|
||||
int32_t field_8F0;
|
||||
int32_t field_8F4;
|
||||
int32_t field_8F8;
|
||||
int32_t field_8FC;
|
||||
int32_t field_900;
|
||||
int32_t field_904;
|
||||
int32_t field_908;
|
||||
int32_t field_90C;
|
||||
int32_t field_910;
|
||||
int32_t field_914;
|
||||
int32_t field_918;
|
||||
int32_t field_91C;
|
||||
int32_t field_920;
|
||||
int32_t field_924;
|
||||
int32_t field_928;
|
||||
int32_t field_92C;
|
||||
int32_t field_930;
|
||||
int32_t field_934;
|
||||
int32_t field_938;
|
||||
int32_t field_93C;
|
||||
int32_t field_940;
|
||||
int32_t field_944;
|
||||
int32_t field_948;
|
||||
int32_t field_94C;
|
||||
int32_t field_950;
|
||||
int32_t field_954;
|
||||
int32_t field_958;
|
||||
int32_t field_95C;
|
||||
int32_t field_960;
|
||||
int32_t field_964;
|
||||
int32_t field_968;
|
||||
int32_t field_96C;
|
||||
int32_t field_970;
|
||||
int32_t field_974;
|
||||
int32_t field_978;
|
||||
int32_t field_97C;
|
||||
int32_t field_980;
|
||||
int32_t field_984;
|
||||
int32_t field_988;
|
||||
int32_t field_98C;
|
||||
int32_t field_990;
|
||||
int32_t field_994;
|
||||
int32_t field_998;
|
||||
int32_t field_99C;
|
||||
int32_t field_9A0;
|
||||
int32_t field_9A4;
|
||||
int32_t field_9A8;
|
||||
int32_t field_9AC;
|
||||
int32_t field_9B0;
|
||||
int32_t field_9B4;
|
||||
int32_t field_9B8;
|
||||
int32_t field_9BC;
|
||||
int32_t field_9C0;
|
||||
int32_t field_9C4;
|
||||
int32_t field_9C8;
|
||||
int32_t field_9CC;
|
||||
int32_t field_9D0;
|
||||
int32_t field_9D4;
|
||||
int32_t field_9D8;
|
||||
int32_t field_9DC;
|
||||
int32_t field_9E0;
|
||||
int32_t field_9E4;
|
||||
int32_t field_9E8;
|
||||
int32_t field_9EC;
|
||||
int32_t field_9F0;
|
||||
int32_t field_9F4;
|
||||
int32_t field_9F8;
|
||||
int32_t field_9FC;
|
||||
int32_t field_A00;
|
||||
int32_t field_A04;
|
||||
int32_t field_A08;
|
||||
int32_t field_A0C;
|
||||
int32_t field_A10;
|
||||
int32_t field_A14;
|
||||
int32_t field_A18;
|
||||
int32_t field_A1C;
|
||||
int32_t field_A20;
|
||||
int32_t field_A24;
|
||||
int32_t field_A28;
|
||||
int32_t field_A2C;
|
||||
int32_t field_A30;
|
||||
int32_t field_A34;
|
||||
int32_t field_A38;
|
||||
int32_t field_A3C;
|
||||
int32_t field_A40;
|
||||
int32_t field_A44;
|
||||
int32_t field_A48;
|
||||
int32_t field_A4C;
|
||||
int32_t field_A50;
|
||||
int32_t field_A54;
|
||||
int32_t field_A58;
|
||||
int32_t field_A5C;
|
||||
int32_t field_A60;
|
||||
int32_t field_A64;
|
||||
int32_t field_A68;
|
||||
int32_t field_A6C;
|
||||
int32_t field_A70;
|
||||
int32_t field_A74;
|
||||
int32_t field_A78;
|
||||
int32_t field_A7C;
|
||||
int32_t field_A80;
|
||||
int32_t field_A84;
|
||||
int32_t field_A88;
|
||||
int32_t field_A8C;
|
||||
int32_t field_A90;
|
||||
int32_t field_A94;
|
||||
int32_t field_A98;
|
||||
int32_t field_A9C;
|
||||
int32_t field_AA0;
|
||||
int32_t field_AA4;
|
||||
int32_t field_AA8;
|
||||
int32_t field_AAC;
|
||||
int32_t field_AB0;
|
||||
int32_t field_AB4;
|
||||
int32_t field_AB8;
|
||||
int32_t field_ABC;
|
||||
int32_t field_AC0;
|
||||
int32_t field_AC4;
|
||||
int32_t field_AC8;
|
||||
int32_t field_ACC;
|
||||
int32_t field_AD0;
|
||||
int32_t field_AD4;
|
||||
int32_t field_AD8;
|
||||
int32_t field_ADC;
|
||||
int32_t field_AE0;
|
||||
int32_t field_AE4;
|
||||
int32_t field_AE8;
|
||||
int32_t field_AEC;
|
||||
int32_t field_AF0;
|
||||
int32_t field_AF4;
|
||||
int32_t field_AF8;
|
||||
int32_t field_AFC;
|
||||
int32_t field_B00;
|
||||
int32_t field_B04;
|
||||
int32_t field_B08;
|
||||
int32_t field_B0C;
|
||||
int32_t field_B10;
|
||||
int32_t field_B14;
|
||||
int32_t field_B18;
|
||||
int32_t field_B1C;
|
||||
int32_t field_B20;
|
||||
int32_t field_B24;
|
||||
int32_t field_B28;
|
||||
int32_t field_B2C;
|
||||
int32_t field_B30;
|
||||
int32_t field_B34;
|
||||
int32_t field_B38;
|
||||
int32_t field_B3C;
|
||||
int32_t field_B40;
|
||||
int32_t field_B44;
|
||||
int32_t field_B48;
|
||||
int32_t field_B4C;
|
||||
int32_t field_B50;
|
||||
int32_t field_B54;
|
||||
int32_t field_B58;
|
||||
int32_t field_B5C;
|
||||
int32_t field_B60;
|
||||
int32_t field_B64;
|
||||
int32_t field_B68;
|
||||
int32_t field_B6C;
|
||||
int32_t field_B70;
|
||||
int32_t field_B74;
|
||||
int32_t field_B78;
|
||||
int32_t field_B7C;
|
||||
int32_t field_B80;
|
||||
int32_t field_B84;
|
||||
int32_t field_B88;
|
||||
int32_t field_B8C;
|
||||
int32_t field_B90;
|
||||
int32_t field_B94;
|
||||
int32_t field_B98;
|
||||
int32_t field_B9C;
|
||||
int32_t field_BA0;
|
||||
int32_t field_BA4;
|
||||
int32_t field_BA8;
|
||||
int32_t field_BAC;
|
||||
int32_t field_BB0;
|
||||
int32_t field_BB4;
|
||||
int32_t field_BB8;
|
||||
int32_t field_BBC;
|
||||
int32_t field_BC0;
|
||||
int32_t field_BC4;
|
||||
int32_t field_BC8;
|
||||
int32_t field_BCC;
|
||||
int32_t field_BD0;
|
||||
int32_t field_BD4;
|
||||
int32_t field_BD8;
|
||||
int32_t field_BDC;
|
||||
int32_t field_BE0;
|
||||
int32_t field_BE4;
|
||||
int32_t field_BE8;
|
||||
int32_t field_BEC;
|
||||
int32_t field_BF0;
|
||||
int32_t field_BF4;
|
||||
int32_t field_BF8;
|
||||
int32_t field_BFC;
|
||||
int32_t field_C00;
|
||||
int32_t field_C04;
|
||||
int32_t field_C08;
|
||||
int32_t field_C0C;
|
||||
int32_t field_C10;
|
||||
int32_t field_C14;
|
||||
int32_t field_C18;
|
||||
int32_t field_C1C;
|
||||
int32_t field_C20;
|
||||
int32_t field_C24;
|
||||
int32_t field_C28;
|
||||
int32_t field_C2C;
|
||||
int32_t field_C30;
|
||||
int32_t field_C34;
|
||||
int32_t field_C38;
|
||||
int32_t field_C3C;
|
||||
int32_t field_C40;
|
||||
int32_t field_C44;
|
||||
int32_t field_C48;
|
||||
int32_t field_C4C;
|
||||
int32_t field_C50;
|
||||
int32_t field_C54;
|
||||
int32_t field_C58;
|
||||
int32_t field_C5C;
|
||||
int32_t field_C60;
|
||||
int32_t field_C64;
|
||||
int32_t field_C68;
|
||||
int32_t field_C6C;
|
||||
int32_t field_C70;
|
||||
int32_t field_C74;
|
||||
int32_t field_C78;
|
||||
int32_t field_C7C;
|
||||
int32_t field_C80;
|
||||
int32_t field_C84;
|
||||
int32_t field_C88;
|
||||
int32_t field_C8C;
|
||||
int32_t field_C90;
|
||||
int32_t field_C94;
|
||||
int32_t field_C98;
|
||||
int32_t field_C9C;
|
||||
int32_t field_CA0;
|
||||
int32_t field_CA4;
|
||||
int32_t field_CA8;
|
||||
int32_t field_CAC;
|
||||
int32_t field_CB0;
|
||||
int32_t field_CB4;
|
||||
int32_t field_CB8;
|
||||
int32_t field_CBC;
|
||||
int32_t field_CC0;
|
||||
int32_t field_CC4;
|
||||
int32_t field_CC8;
|
||||
int32_t field_CCC;
|
||||
int32_t field_CD0;
|
||||
int32_t field_CD4;
|
||||
int32_t field_CD8;
|
||||
int32_t field_CDC;
|
||||
int32_t field_CE0;
|
||||
int32_t field_CE4;
|
||||
int32_t field_CE8;
|
||||
int32_t field_CEC;
|
||||
int32_t field_CF0;
|
||||
int32_t field_CF4;
|
||||
int32_t field_CF8;
|
||||
int32_t field_CFC;
|
||||
int32_t field_D00;
|
||||
int32_t field_D04;
|
||||
int32_t field_D08;
|
||||
int32_t field_D0C;
|
||||
int32_t field_D10;
|
||||
int32_t field_D14;
|
||||
int32_t field_D18;
|
||||
int32_t field_D1C;
|
||||
int32_t field_D20;
|
||||
int32_t field_D24;
|
||||
int32_t field_D28;
|
||||
int32_t field_D2C;
|
||||
int32_t field_D30;
|
||||
int32_t field_D34;
|
||||
int32_t field_D38;
|
||||
int32_t field_D3C;
|
||||
int32_t field_D40;
|
||||
int32_t field_D44;
|
||||
int32_t field_D48;
|
||||
int32_t field_D4C;
|
||||
int32_t field_D50;
|
||||
int32_t field_D54;
|
||||
int32_t field_D58;
|
||||
int32_t field_D5C;
|
||||
int32_t field_D60;
|
||||
int32_t field_D64;
|
||||
int32_t field_D68;
|
||||
int32_t field_D6C;
|
||||
int32_t field_D70;
|
||||
int32_t field_D74;
|
||||
int32_t field_D78;
|
||||
int32_t field_D7C;
|
||||
int32_t field_D80;
|
||||
int32_t field_D84;
|
||||
int32_t field_D88;
|
||||
int32_t field_D8C;
|
||||
int32_t field_D90;
|
||||
int32_t field_D94;
|
||||
int32_t field_D98;
|
||||
int32_t field_D9C;
|
||||
int32_t field_DA0;
|
||||
int32_t field_DA4;
|
||||
int32_t field_DA8;
|
||||
int32_t field_DAC;
|
||||
int32_t field_DB0;
|
||||
int32_t field_DB4;
|
||||
int32_t field_DB8;
|
||||
int32_t field_DBC;
|
||||
int32_t field_DC0;
|
||||
int32_t field_DC4;
|
||||
int32_t field_DC8;
|
||||
int32_t field_DCC;
|
||||
int32_t field_DD0;
|
||||
int32_t field_DD4;
|
||||
int32_t field_DD8;
|
||||
int32_t field_DDC;
|
||||
int32_t field_DE0;
|
||||
int32_t field_DE4;
|
||||
int32_t field_DE8;
|
||||
int32_t field_DEC;
|
||||
int32_t field_DF0;
|
||||
int32_t field_DF4;
|
||||
int32_t field_DF8;
|
||||
int32_t field_DFC;
|
||||
int32_t field_E00;
|
||||
int32_t field_E04;
|
||||
int32_t field_E08;
|
||||
int32_t field_E0C;
|
||||
int32_t field_E10;
|
||||
int32_t field_E14;
|
||||
int32_t field_E18;
|
||||
int32_t field_E1C;
|
||||
int32_t field_E20;
|
||||
int32_t field_E24;
|
||||
int32_t field_E28;
|
||||
int32_t field_E2C;
|
||||
int32_t field_E30;
|
||||
int8_t field_E34;
|
||||
int8_t game_opts;
|
||||
int8_t field_E36;
|
||||
int8_t field_E37;
|
||||
int32_t field_E38;
|
||||
int32_t field_E3C;
|
||||
int32_t field_E40;
|
||||
int32_t field_E44;
|
||||
int32_t field_E48;
|
||||
int32_t field_E4C;
|
||||
int32_t field_E50;
|
||||
int32_t field_E54;
|
||||
int32_t field_E58;
|
||||
int32_t field_E5C;
|
||||
int32_t field_E60;
|
||||
int32_t field_E64;
|
||||
int32_t field_E68;
|
||||
int32_t field_E6C;
|
||||
int32_t field_E70;
|
||||
int32_t field_E74;
|
||||
int32_t field_E78;
|
||||
int32_t field_E7C;
|
||||
int32_t field_E80;
|
||||
int32_t field_E84;
|
||||
int32_t field_E88;
|
||||
int32_t field_E8C;
|
||||
int32_t field_E90;
|
||||
int32_t field_E94;
|
||||
int32_t field_E98;
|
||||
int32_t field_E9C;
|
||||
int32_t field_EA0;
|
||||
int32_t field_EA4;
|
||||
int32_t field_EA8;
|
||||
int32_t field_EAC;
|
||||
int32_t field_EB0;
|
||||
int32_t field_EB4;
|
||||
int32_t field_EB8;
|
||||
int32_t field_EBC;
|
||||
int32_t field_EC0;
|
||||
int32_t field_EC4;
|
||||
int32_t field_EC8;
|
||||
int32_t field_ECC;
|
||||
int32_t field_ED0;
|
||||
int32_t field_ED4;
|
||||
int32_t field_ED8;
|
||||
int32_t field_EDC;
|
||||
int32_t field_EE0;
|
||||
int32_t field_EE4;
|
||||
int32_t field_EE8;
|
||||
int32_t field_EEC;
|
||||
int32_t field_EF0;
|
||||
int32_t field_EF4;
|
||||
int32_t field_EF8;
|
||||
int32_t field_EFC;
|
||||
};
|
||||
@@ -0,0 +1,150 @@
|
||||
#include "PlayerDataManager.h"
|
||||
#include <string>
|
||||
#include "../framework.h"
|
||||
#include "../Constants.h"
|
||||
#include "../Input/Keyboard/Keyboard.h"
|
||||
#include "../FileSystem/ConfigFile.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
const std::string PLAYER_DATA_FILE_NAME = "playerdata.ini";
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
PlayerDataManager::PlayerDataManager()
|
||||
{
|
||||
}
|
||||
|
||||
PlayerDataManager::~PlayerDataManager()
|
||||
{
|
||||
if (customPlayerData != nullptr)
|
||||
delete customPlayerData;
|
||||
}
|
||||
|
||||
const char* PlayerDataManager::GetDisplayName()
|
||||
{
|
||||
return "player_data_manager";
|
||||
}
|
||||
|
||||
void PlayerDataManager::Initialize(ComponentsManager*)
|
||||
{
|
||||
playerData = (PlayerData*)PLAYER_DATA_ADDRESS;
|
||||
|
||||
ApplyPatch();
|
||||
LoadConfig();
|
||||
ApplyCustomData();
|
||||
}
|
||||
|
||||
void PlayerDataManager::Update()
|
||||
{
|
||||
ApplyCustomData();
|
||||
|
||||
if (false && Input::Keyboard::GetInstance()->IsTapped(VK_F12))
|
||||
{
|
||||
printf("[TLAC] PlayerDataManager::Update(): Loading config...\n");
|
||||
LoadConfig();
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDataManager::ApplyPatch()
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
// prevent the PlayerData from being reset
|
||||
*(uint8_t*)(SET_DEFAULT_PLAYER_DATA_ADDRESS) = RET_OPCODE;
|
||||
}
|
||||
VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), oldProtect, &oldProtect);
|
||||
|
||||
// allow player to select the module and extra item
|
||||
VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte) * 2, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
*(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS) = 0xB0; // xor al,al -> ld al,1
|
||||
*(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS + 0x1) = 0x01;
|
||||
}
|
||||
VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte) * 2, oldProtect, &oldProtect);
|
||||
|
||||
// fix annoying behavior of closing after changing module or item (don't yet know the reason, maybe NW/Card checks)
|
||||
{
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
*(uint8_t*)(MODSELECTOR_CLOSE_AFTER_MODULE) = JNE_OPCODE;
|
||||
}
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), oldProtect, &oldProtect);
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
{
|
||||
*(uint8_t*)(MODSELECTOR_CLOSE_AFTER_CUSTOMIZE) = JNE_OPCODE;
|
||||
}
|
||||
VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), oldProtect, &oldProtect);
|
||||
}
|
||||
}
|
||||
|
||||
void PlayerDataManager::LoadConfig()
|
||||
{
|
||||
if (playerData == nullptr)
|
||||
return;
|
||||
|
||||
FileSystem::ConfigFile config(framework::GetModuleDirectory(), PLAYER_DATA_FILE_NAME);
|
||||
|
||||
if (!config.OpenRead())
|
||||
return;
|
||||
|
||||
if (customPlayerData != nullptr)
|
||||
delete customPlayerData;
|
||||
|
||||
customPlayerData = new CustomPlayerData();
|
||||
config.TryGetValue("player_name", &customPlayerData->PlayerName);
|
||||
config.TryGetValue("level_name", &customPlayerData->LevelName);
|
||||
|
||||
customPlayerData->LevelPlateId = config.GetIntegerValue("level_plate_id");
|
||||
customPlayerData->SkinEquip = config.GetIntegerValue("skin_equip");
|
||||
customPlayerData->BtnSeEquip = config.GetIntegerValue("btn_se_equip");
|
||||
customPlayerData->SlideSeEquip = config.GetIntegerValue("slide_se_equip");
|
||||
customPlayerData->ChainslideSeEquip = config.GetIntegerValue("chainslide_se_equip");
|
||||
customPlayerData->ShowExcellentClearBorder = config.GetBooleanValue("border_excellent");
|
||||
customPlayerData->ShowGreatClearBorder = config.GetBooleanValue("border_great");
|
||||
customPlayerData->UseCard = config.GetBooleanValue("use_card");
|
||||
customPlayerData->GameModifierOptions = config.GetBooleanValue("gamemode_options");
|
||||
}
|
||||
|
||||
void PlayerDataManager::ApplyCustomData()
|
||||
{
|
||||
// don't want to overwrite the default values
|
||||
auto setIfNotEqual = [](int *target, int value, int comparison)
|
||||
{
|
||||
if (value != comparison)
|
||||
*target = value;
|
||||
};
|
||||
|
||||
setIfNotEqual(&playerData->level_plate_id, customPlayerData->LevelPlateId, 0);
|
||||
setIfNotEqual(&playerData->skin_equip, customPlayerData->SkinEquip, 0);
|
||||
setIfNotEqual(&playerData->btn_se_equip, customPlayerData->BtnSeEquip, -1);
|
||||
setIfNotEqual(&playerData->slide_se_equip, customPlayerData->SlideSeEquip, -1);
|
||||
setIfNotEqual(&playerData->chainslide_se_equip, customPlayerData->ChainslideSeEquip, -1);
|
||||
|
||||
// Display clear borders on the progress bar
|
||||
*(byte*)(PLAYER_DATA_ADDRESS + 0xD94) = (customPlayerData->ShowExcellentClearBorder << 1) | (customPlayerData->ShowGreatClearBorder);
|
||||
|
||||
if (customPlayerData->UseCard)
|
||||
playerData->use_card = 1; // required to allow for module selection
|
||||
|
||||
if (customPlayerData->GameModifierOptions)
|
||||
playerData->game_opts = 1; // hi-speed, etc..
|
||||
|
||||
memset((void*)MODULE_TABLE_START, 0xFF, 128);
|
||||
memset((void*)ITEM_TABLE_START, 0xFF, 128);
|
||||
|
||||
if (customPlayerData->PlayerName != nullptr)
|
||||
{
|
||||
playerData->field_DC = 0x10;
|
||||
playerData->player_name = (char*)customPlayerData->PlayerName->c_str();
|
||||
}
|
||||
|
||||
|
||||
if (customPlayerData->LevelName != nullptr)
|
||||
{
|
||||
playerData->level_name = (char*)customPlayerData->LevelName->c_str();
|
||||
playerData->field_110 = 0xFF;
|
||||
playerData->field_118 = 0x1F;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "PlayerData.h"
|
||||
#include "CustomPlayerData.h"
|
||||
#include <string>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class PlayerDataManager : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
PlayerDataManager();
|
||||
~PlayerDataManager();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
PlayerData* playerData;
|
||||
CustomPlayerData* customPlayerData;
|
||||
|
||||
void ApplyPatch();
|
||||
void LoadConfig();
|
||||
void ApplyCustomData();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
#include "ScaleComponent.h"
|
||||
#include <iostream>
|
||||
#include <Windows.h>
|
||||
#include "../Constants.h"
|
||||
#include <stdio.h>
|
||||
#include "../framework.h"
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <tchar.h>
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
|
||||
ScaleComponent::ScaleComponent()
|
||||
{
|
||||
}
|
||||
|
||||
ScaleComponent::~ScaleComponent()
|
||||
{
|
||||
}
|
||||
|
||||
const char* ScaleComponent::GetDisplayName()
|
||||
{
|
||||
return "scale_component";
|
||||
}
|
||||
|
||||
void ScaleComponent::Initialize(ComponentsManager*)
|
||||
{
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD24, 7, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((byte*)0x00000001404ACD24 + 0) = 0x44;
|
||||
*((byte*)0x00000001404ACD24 + 1) = 0x8B;
|
||||
*((byte*)0x00000001404ACD24 + 2) = 0x0D;
|
||||
*((byte*)0x00000001404ACD24 + 3) = 0xD1;
|
||||
*((byte*)0x00000001404ACD24 + 4) = 0x08;
|
||||
*((byte*)0x00000001404ACD24 + 5) = 0xD0;
|
||||
*((byte*)0x00000001404ACD24 + 6) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD24, 7, oldProtect, &bck);
|
||||
}
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD2B, 7, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((byte*)0x00000001404ACD2B + 0) = 0x44;
|
||||
*((byte*)0x00000001404ACD2B + 1) = 0x8B;
|
||||
*((byte*)0x00000001404ACD2B + 2) = 0x05;
|
||||
*((byte*)0x00000001404ACD2B + 3) = 0xC6;
|
||||
*((byte*)0x00000001404ACD2B + 4) = 0x08;
|
||||
*((byte*)0x00000001404ACD2B + 5) = 0xD0;
|
||||
*((byte*)0x00000001404ACD2B + 6) = 0x00;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD2B, 7, oldProtect, &bck);
|
||||
}
|
||||
{
|
||||
DWORD oldProtect, bck;
|
||||
VirtualProtect((BYTE*)0x00000001405030A0, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
*((byte*)0x00000001405030A0 + 0) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 1) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 2) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 3) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 4) = 0x90;
|
||||
*((byte*)0x00000001405030A0 + 5) = 0x90;
|
||||
VirtualProtect((BYTE*)0x00000001404ACD2B, 6, oldProtect, &bck);
|
||||
}
|
||||
}
|
||||
|
||||
void ScaleComponent::Update()
|
||||
{
|
||||
uiAspectRatio = (float*)UI_ASPECT_RATIO;
|
||||
uiWidth = (float*)UI_WIDTH_ADDRESS;
|
||||
uiHeight = (float*)UI_HEIGHT_ADDRESS;
|
||||
fb1Height = (int*)FB1_HEIGHT_ADDRESS;
|
||||
fb1Width = (int*)FB1_WIDTH_ADDRESS;
|
||||
//fb2Height = (int*)FB2_HEIGHT_ADDRESS;
|
||||
//fb2Width = (int*)FB2_WIDTH_ADDRESS;
|
||||
fbAspectRatio = (double*)FB_ASPECT_RATIO;
|
||||
RECT hWindow;
|
||||
GetClientRect(TLAC::framework::DivaWindowHandle, &hWindow);
|
||||
*uiAspectRatio = (float)(hWindow.right - hWindow.left) / (float)(hWindow.bottom - hWindow.top);
|
||||
*fbAspectRatio = (double)(hWindow.right - hWindow.left) / (double)(hWindow.bottom - hWindow.top);
|
||||
*uiWidth = hWindow.right - hWindow.left;
|
||||
*uiHeight = hWindow.bottom - hWindow.top;
|
||||
*fb1Width = hWindow.right - hWindow.left;
|
||||
*fb1Height = hWindow.bottom - hWindow.top;
|
||||
//*fb2Width = hWindow.right - hWindow.left;
|
||||
//*fb2Height = hWindow.bottom - hWindow.top;
|
||||
|
||||
*((int*)0x00000001411AD608) = 0;
|
||||
|
||||
*((int*)0x0000000140EDA8E4) = *(int*)0x0000000140EDA8BC;
|
||||
*((int*)0x0000000140EDA8E8) = *(int*)0x0000000140EDA8C0;
|
||||
|
||||
*(float*)0x00000001411A1900 = 0;
|
||||
*(float*)0x00000001411A1904 = (float)*(int*)0x0000000140EDA8BC;
|
||||
*(float*)0x00000001411A1908 = (float)*(int*)0x0000000140EDA8C0;
|
||||
//*((int*)0x00000001411AD5F8) = hWindow.right - hWindow.left;
|
||||
//*((int*)0x00000001411AD5FC) = hWindow.bottom - hWindow.top;
|
||||
|
||||
//*((int*)0x00000001411ABB48) = hWindow.right - hWindow.left;
|
||||
//*((int*)0x00000001411ABB4C) = hWindow.bottom - hWindow.top;
|
||||
|
||||
//*((int*)0x00000001411ABB5C) = (int)(*((int*)0x00000001411ABB54) * ((float)8 / (float)9)); //wtf??
|
||||
}
|
||||
|
||||
void ScaleComponent::UpdateInput()
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include "GameState.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class ScaleComponent : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
ScaleComponent();
|
||||
~ScaleComponent();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
virtual void UpdateInput() override;
|
||||
|
||||
const int updatesPerFrame = 39;
|
||||
|
||||
float* uiAspectRatio;
|
||||
float* uiWidth;
|
||||
float* uiHeight;
|
||||
|
||||
int* fb1Width;
|
||||
int* fb1Height;
|
||||
int* fb2Width;
|
||||
int* fb2Height;
|
||||
|
||||
double* fbAspectRatio;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "StageManager.h"
|
||||
#include "../Constants.h"
|
||||
#include <windows.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
StageManager::StageManager()
|
||||
{
|
||||
}
|
||||
|
||||
StageManager::~StageManager()
|
||||
{
|
||||
}
|
||||
|
||||
const char* StageManager::GetDisplayName()
|
||||
{
|
||||
return "stage_manager";
|
||||
}
|
||||
|
||||
void StageManager::Initialize(ComponentsManager*)
|
||||
{
|
||||
// add the offset between moving 2 into ebx and the start of the function
|
||||
int32_t* playCount = (int32_t*)(((uint8_t*)PLAYS_PER_SESSION_GETTER_ADDRESS) + 0x7);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(playCount, sizeof(int32_t), PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
// set ’Ê�탂�[ƒh per session play count
|
||||
*playCount = GetPlayCount();
|
||||
}
|
||||
|
||||
void StageManager::Update()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t StageManager::GetPlayCount()
|
||||
{
|
||||
return INT32_MAX;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
#include <stdint.h>
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class StageManager : public EmulatorComponent
|
||||
{
|
||||
public:
|
||||
StageManager();
|
||||
~StageManager();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
int32_t GetPlayCount();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "SysTimer.h"
|
||||
#include "../Constants.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
SysTimer::SysTimer()
|
||||
{
|
||||
}
|
||||
|
||||
SysTimer::~SysTimer()
|
||||
{
|
||||
}
|
||||
|
||||
const char* SysTimer::GetDisplayName()
|
||||
{
|
||||
return "sys_timer";
|
||||
}
|
||||
|
||||
void SysTimer::Initialize(ComponentsManager*)
|
||||
{
|
||||
selPvTime = GetSysTimePtr((void*)SEL_PV_TIME_ADDRESS);
|
||||
}
|
||||
|
||||
void SysTimer::Update()
|
||||
{
|
||||
// account for the decrement that occures during this frame
|
||||
*selPvTime = SEL_PV_FREEZE_TIME * SYS_TIME_FACTOR + 1;
|
||||
}
|
||||
|
||||
int* SysTimer::GetSysTimePtr(void *address)
|
||||
{
|
||||
return (int*)address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include "EmulatorComponent.h"
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
class SysTimer : public EmulatorComponent
|
||||
{
|
||||
const int SYS_TIME_FACTOR = 60;
|
||||
const int SEL_PV_FREEZE_TIME = 39;
|
||||
|
||||
public:
|
||||
SysTimer();
|
||||
~SysTimer();
|
||||
|
||||
virtual const char* GetDisplayName() override;
|
||||
|
||||
virtual void Initialize(ComponentsManager*) override;
|
||||
virtual void Update() override;
|
||||
|
||||
private:
|
||||
int* selPvTime;
|
||||
int* GetSysTimePtr(void *address);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
constexpr uint8_t NOP_OPCODE = 0x90;
|
||||
constexpr uint8_t RET_OPCODE = 0xC3;
|
||||
constexpr uint8_t JMP_OPCODE = 0xE9;
|
||||
constexpr uint8_t JNE_OPCODE = 0x85;
|
||||
|
||||
//constexpr uint64_t ENGINE_UPDATE_HOOK_TARGET_ADDRESS = 0x000000014018CC40;
|
||||
constexpr uint64_t ENGINE_UPDATE_INPUT_ADDRESS = 0x000000014018CBB0;
|
||||
|
||||
constexpr uint64_t CURRENT_GAME_STATE_ADDRESS = 0x0000000140EDA810;
|
||||
constexpr uint64_t RESOLUTION_WIDTH_ADDRESS = 0x0000000140EDA8BC;
|
||||
constexpr uint64_t RESOLUTION_HEIGHT_ADDRESS = 0x0000000140EDA8C0;
|
||||
|
||||
constexpr uint64_t SYSTEM_WARNING_ELAPSED_ADDRESS = (0x00000001411A1430 + 0x68);
|
||||
constexpr uint64_t DATA_INIT_STATE_ADDRESS = 0x0000000140EDA7A8;
|
||||
|
||||
constexpr uint64_t AET_FRAME_DURATION_ADDRESS = 0x00000001409A0A58;
|
||||
constexpr uint64_t PV_FRAME_RATE_ADDRESS = 0x0000000140EDA7CC;
|
||||
constexpr uint64_t FRAME_SPEED_ADDRESS = 0x0000000140EDA798;
|
||||
constexpr uint64_t FRAME_RATE_ADDRESS = 0x0000000140EDA6D0;
|
||||
|
||||
constexpr uint64_t DW_GUI_DISPLAY_INSTANCE_PTR_ADDRESS = 0x0000000141190108;
|
||||
constexpr uint64_t INPUT_STATE_PTR_ADDRESS = 0x0000000140EDA330;
|
||||
constexpr uint64_t SLIDER_CTRL_TASK_ADDRESS = 0x000000014CC5DE40;
|
||||
constexpr uint64_t TASK_TOUCH_ADDRESS = 0x000000014CC9EC30;
|
||||
constexpr uint64_t SEL_PV_TIME_ADDRESS = 0x000000014CC12498;
|
||||
constexpr uint64_t PLAYER_DATA_ADDRESS = 0x00000001411A8850;
|
||||
constexpr uint64_t SET_DEFAULT_PLAYER_DATA_ADDRESS = 0x00000001404A7370;
|
||||
constexpr uint64_t PLAYS_PER_SESSION_GETTER_ADDRESS = 0x000000014038AEE0;
|
||||
constexpr uint64_t PV_SEL_SLOTS_TO_SCROLL = 0x000000014CC12470;
|
||||
constexpr uint64_t PV_SEL_SLOTS_CONST = 0x000000014CC119C8;
|
||||
constexpr uint64_t MODULE_SEL_SLOTS_TO_SCROLL = 0x00000001418047EC;
|
||||
constexpr uint64_t MODULE_IS_RECOMMENDED = 0x00000001418047E0;
|
||||
|
||||
constexpr uint64_t CAMERA_ADDRESS = 0x0000000140FBC2C0;
|
||||
constexpr uint64_t CAMERA_POS_SETTER_ADDRESS = 0x00000001401F9460;
|
||||
constexpr uint64_t CAMERA_INTR_SETTER_ADDRESS = 0x00000001401F93F0;
|
||||
constexpr uint64_t CAMERA_ROT_SETTER_ADDRESS = 0x00000001401F9480;
|
||||
constexpr uint64_t CAMERA_PERS_SETTER_ADDRESS = 0x00000001401F9430;
|
||||
|
||||
constexpr uint64_t UPDATE_TASKS_ADDRESS = 0x000000014019B980;
|
||||
constexpr uint64_t GLUT_SET_CURSOR_ADDRESS = 0x00000001408B68E6;
|
||||
constexpr uint64_t CHANGE_MODE_ADDRESS = 0x00000001401953D0;
|
||||
constexpr uint64_t CHANGE_SUB_MODE_ADDRESS = 0x0000000140195260;
|
||||
|
||||
constexpr uint64_t TGT_TYPE_BASE_ADDRESS = 0x0000000140D0B69C;
|
||||
constexpr uint64_t TGT_REMAINING_DURATION_BASE_ADDRESS = 0x0000000140D0B6A0;
|
||||
constexpr uint64_t TGT_HIT_STATE_BASE_ADDRESS = 0x0000000140D0BAE4;
|
||||
constexpr uint64_t TGT_ON_SCREEN_ADDRESS = 0x0000000140D0B678;
|
||||
|
||||
constexpr uint64_t HOLD_STATE_ADDRESS = 0x0000000140D1E20C;
|
||||
constexpr uint64_t MAX_HOLD_STATE_ADDRESS = 0x0000000140D1E234;
|
||||
|
||||
constexpr uint64_t CHECK_SOMETHING_SET_MODULE_ADDRESS = 0x0000000140581C78;
|
||||
constexpr uint64_t MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS = 0x00000001405869AD;
|
||||
constexpr uint64_t MODSELECTOR_CLOSE_AFTER_MODULE = 0x0000000140583B45;
|
||||
constexpr uint64_t MODSELECTOR_CLOSE_AFTER_CUSTOMIZE = 0x0000000140583C8C;
|
||||
constexpr uint64_t MODULE_TABLE_START = PLAYER_DATA_ADDRESS + 0x140;
|
||||
constexpr uint64_t MODULE_TABLE_END = MODULE_TABLE_START + 128;
|
||||
constexpr uint64_t ITEM_TABLE_START = PLAYER_DATA_ADDRESS + 0x2B8;
|
||||
constexpr uint64_t ITEM_TABLE_END = ITEM_TABLE_START + 128;
|
||||
|
||||
constexpr uint64_t FB_WIDTH_ADDRESS = 0x00000001411ABCA8;
|
||||
constexpr uint64_t FB_HEIGHT_ADDRESS = 0x00000001411ABCAC;
|
||||
constexpr uint64_t FB1_WIDTH_ADDRESS = 0x00000001411AD5F8;
|
||||
constexpr uint64_t FB1_HEIGHT_ADDRESS = 0x00000001411AD5FC;
|
||||
constexpr uint64_t FB2_WIDTH_ADDRESS = 0x0000000140EDA8E4;
|
||||
constexpr uint64_t FB2_HEIGHT_ADDRESS = 0x0000000140EDA8E8;
|
||||
|
||||
constexpr uint64_t FB_RESOLUTION_WIDTH_ADDRESS = 0x00000001411ABB50;
|
||||
constexpr uint64_t FB_RESOLUTION_HEIGHT_ADDRESS = 0x00000001411ABB54;
|
||||
|
||||
constexpr uint64_t UI_WIDTH_ADDRESS = 0x000000014CC621E4;
|
||||
constexpr uint64_t UI_HEIGHT_ADDRESS = 0x000000014CC621E8;
|
||||
|
||||
constexpr uint64_t FB_ASPECT_RATIO = 0x0000000140FBC2E8;
|
||||
constexpr uint64_t UI_ASPECT_RATIO = 0x000000014CC621D0;
|
||||
|
||||
#define XINPUT_A 0x00
|
||||
#define XINPUT_B 0x01
|
||||
#define XINPUT_X 0x02
|
||||
#define XINPUT_Y 0x03
|
||||
#define XINPUT_UP 0x10
|
||||
#define XINPUT_DOWN 0x11
|
||||
#define XINPUT_LEFT 0x12
|
||||
#define XINPUT_RIGHT 0x13
|
||||
#define XINPUT_LS 0x20
|
||||
#define XINPUT_RS 0x21
|
||||
#define XINPUT_LT 0x22
|
||||
#define XINPUT_RT 0x23
|
||||
#define XINPUT_START 0x30
|
||||
#define XINPUT_BACK 0x31
|
||||
#define XINPUT_LUP 0x40
|
||||
#define XINPUT_LDOWN 0x41
|
||||
#define XINPUT_LLEFT 0x42
|
||||
#define XINPUT_LRIGHT 0x43
|
||||
#define XINPUT_RUP 0x50
|
||||
#define XINPUT_RDOWN 0x51
|
||||
#define XINPUT_RLEFT 0x52
|
||||
#define XINPUT_RRIGHT 0x53
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user