├── .github └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── Android.mk ├── Application.mk ├── ES3Shader.h ├── GTASA └── files │ └── shaders │ ├── fragment │ ├── blur.glsl │ ├── contrast.glsl │ ├── grading.glsl │ └── shadowResolve.glsl │ └── vertex │ └── contrast.glsl ├── LICENSE ├── README.md ├── isasl.h └── main.cpp /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: AML Mod Compiler 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | 14 | - name: Checkout repository... 15 | uses: actions/checkout@v3 16 | with: 17 | submodules: recursive 18 | 19 | - name: Setup SSH keys... 20 | uses: webfactory/ssh-agent@v0.8.0 21 | with: 22 | ssh-private-key: | 23 | ${{ secrets.SSH }} 24 | 25 | - name: Download AndroidModLoader`s mod template... 26 | uses: wei/wget@v1 27 | with: 28 | args: -O ./AML_src.zip https://github.com/RusJJ/AndroidModLoader/archive/refs/heads/main.zip 29 | 30 | - name: Install AndroidModLoader`s mod template... 31 | run: | 32 | unzip ./AML_src.zip 33 | mv ./AndroidModLoader-main/mod ./mod 34 | 35 | - name: Get GTA:SA structures file (private)... 36 | run: | 37 | git clone ssh://git@github.com/RusJJ/GTASAAndroid_Structs.git ./structs 38 | mv ./structs/* ./ 39 | 40 | - name: Install Android NDK (r24)... 41 | uses: nttld/setup-ndk@v1.2.0 42 | with: 43 | ndk-version: r24 44 | local-cache: true 45 | 46 | - name: Build the code... 47 | run: ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk 48 | 49 | - name: Upload the mod! 50 | uses: actions/upload-artifact@v3 51 | with: 52 | name: compiled-mod.zip 53 | path: ./libs 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | *.sbr 86 | *.tlb 87 | *.tli 88 | *.tlh 89 | *.tmp 90 | *.tmp_proj 91 | *_wpftmp.csproj 92 | *.log 93 | *.tlog 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 298 | *.vbp 299 | 300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 301 | *.dsw 302 | *.dsp 303 | 304 | # Visual Studio 6 technical files 305 | *.ncb 306 | *.aps 307 | 308 | # Visual Studio LightSwitch build output 309 | **/*.HTMLClient/GeneratedArtifacts 310 | **/*.DesktopClient/GeneratedArtifacts 311 | **/*.DesktopClient/ModelManifest.xml 312 | **/*.Server/GeneratedArtifacts 313 | **/*.Server/ModelManifest.xml 314 | _Pvt_Extensions 315 | 316 | # Paket dependency manager 317 | .paket/paket.exe 318 | paket-files/ 319 | 320 | # FAKE - F# Make 321 | .fake/ 322 | 323 | # CodeRush personal settings 324 | .cr/personal 325 | 326 | # Python Tools for Visual Studio (PTVS) 327 | __pycache__/ 328 | *.pyc 329 | 330 | # Cake - Uncomment if you are using it 331 | # tools/** 332 | # !tools/packages.config 333 | 334 | # Tabs Studio 335 | *.tss 336 | 337 | # Telerik's JustMock configuration file 338 | *.jmconfig 339 | 340 | # BizTalk build output 341 | *.btp.cs 342 | *.btm.cs 343 | *.odx.cs 344 | *.xsd.cs 345 | 346 | # OpenCover UI analysis results 347 | OpenCover/ 348 | 349 | # Azure Stream Analytics local run output 350 | ASALocalRun/ 351 | 352 | # MSBuild Binary and Structured Log 353 | *.binlog 354 | 355 | # NVidia Nsight GPU debugger configuration file 356 | *.nvuser 357 | 358 | # MFractors (Xamarin productivity tool) working folder 359 | .mfractor/ 360 | 361 | # Local History for Visual Studio 362 | .localhistory/ 363 | 364 | # Visual Studio History (VSHistory) files 365 | .vshistory/ 366 | 367 | # BeatPulse healthcheck temp database 368 | healthchecksdb 369 | 370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 371 | MigrationBackup/ 372 | 373 | # Ionide (cross platform F# VS Code tools) working folder 374 | .ionide/ 375 | 376 | # Fody - auto-generated XML schema 377 | FodyWeavers.xsd 378 | 379 | # VS Code files for those working on multiple tools 380 | .vscode/* 381 | !.vscode/settings.json 382 | !.vscode/tasks.json 383 | !.vscode/launch.json 384 | !.vscode/extensions.json 385 | *.code-workspace 386 | 387 | # Local History for Visual Studio Code 388 | .history/ 389 | 390 | # Windows Installer files from build outputs 391 | *.cab 392 | *.msi 393 | *.msix 394 | *.msm 395 | *.msp 396 | 397 | # JetBrains Rider 398 | *.sln.iml 399 | 400 | # Own 401 | mod/ 402 | libs/ 403 | *.bak 404 | build.ps1 405 | ndkpath.txt 406 | GTASA_ENUMS.h 407 | GTASA_STRUCTS.h 408 | RW_STRUCTS.h 409 | .vscode/settings.json 410 | GTA_SHARED.h 411 | GTASA_DECLS.h 412 | GTASA_STRUCTS_210.h 413 | GTASADE_STRUCTS.h 414 | GTAVC_ENUMS.h 415 | GTAVC_STRUCTS.h 416 | RW_STRUCTS_210.h 417 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "AArchASMHelper"] 2 | path = AArchASMHelper 3 | url = https://github.com/RusJJ/AArchASMHelper 4 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | LOCAL_CPP_EXTENSION := .cpp .cc 5 | ifeq ($(TARGET_ARCH_ABI), armeabi-v7a) 6 | LOCAL_MODULE := SAShaderL 7 | else 8 | LOCAL_MODULE := SAShaderL64 9 | endif 10 | LOCAL_SRC_FILES := main.cpp mod/logger.cpp 11 | LOCAL_CFLAGS += -O2 -mfloat-abi=softfp -DNDEBUG -std=c++14 12 | LOCAL_LDLIBS += -llog 13 | include $(BUILD_SHARED_LIBRARY) 14 | -------------------------------------------------------------------------------- /Application.mk: -------------------------------------------------------------------------------- 1 | APP_STL := c++_static 2 | APP_ABI := armeabi-v7a arm64-v8a 3 | APP_OPTIM := release 4 | APP_PLATFORM := android-17 5 | APP_CFLAGS += -Ofast 6 | NDK_TOOLCHAIN_VERSION := clang -------------------------------------------------------------------------------- /ES3Shader.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "isasl.h" 4 | 5 | #ifdef AML32 6 | #include "AArchASMHelper/Thumbv7_ASMHelper.h" 7 | #include "GTASA_STRUCTS.h" 8 | using namespace ThumbV7; 9 | #else 10 | #include "AArchASMHelper/ARMv8_ASMHelper.h" 11 | #include "GTASA_STRUCTS_210.h" 12 | using namespace ARMv8; 13 | #endif 14 | 15 | #define FLAG_ALPHA_TEST 0x01 16 | #define FLAG_LIGHTING 0x02 17 | #define FLAG_ALPHA_MODULATE 0x04 18 | #define FLAG_COLOR_EMISSIVE 0x08 19 | #define FLAG_COLOR 0x10 20 | #define FLAG_TEX0 0x20 21 | #define FLAG_ENVMAP 0x40 // normal envmap 22 | #define FLAG_BONE3 0x80 23 | #define FLAG_BONE4 0x100 24 | #define FLAG_CAMERA_BASED_NORMALS 0x200 25 | #define FLAG_FOG 0x400 26 | #define FLAG_TEXBIAS 0x800 27 | #define FLAG_BACKLIGHT 0x1000 28 | #define FLAG_LIGHT1 0x2000 29 | #define FLAG_LIGHT2 0x4000 30 | #define FLAG_LIGHT3 0x8000 31 | #define FLAG_DETAILMAP 0x10000 32 | #define FLAG_COMPRESSED_TEXCOORD 0x20000 33 | #define FLAG_PROJECT_TEXCOORD 0x40000 34 | #define FLAG_WATER 0x80000 35 | #define FLAG_COLOR2 0x100000 36 | #define FLAG_SPHERE_XFORM 0x800000 // this renders the scene as a sphere map for vehicle reflections 37 | #define FLAG_SPHERE_ENVMAP 0x1000000 // spherical real-time envmap 38 | #define FLAG_TEXMATRIX 0x2000000 39 | #define FLAG_GAMMA 0x4000000 40 | 41 | #define FLAG_CUSTOM_SKY 0x8000000 42 | #define FLAG_CUSTOM_BUILDING 0x10000000 43 | #define FLAG_CUSTOM_POSTPROCESS 0x20000000 44 | #define FLAG_CUSTOM2 0x40000000 45 | #define FLAG_CUSTOM1 0x80000000 46 | 47 | #define CUSTOM_UNIFORMS 128 48 | 49 | struct CustomStaticUniform 50 | { 51 | static int registeredUniforms; 52 | 53 | struct Data 54 | { 55 | union 56 | { 57 | int i[4]; 58 | uint32_t u[4]; 59 | float f[4]; 60 | }; 61 | union 62 | { 63 | int* iptr; 64 | uint32_t* uptr; 65 | float* fptr; 66 | }; 67 | } data, prevdata; 68 | const char* name; 69 | int id; 70 | eUniformValueType type; 71 | bool alwaysUpdate; // no checks 72 | uint8_t count; // 1-4 73 | 74 | inline void SetInt(int dataNum, int value) 75 | { 76 | prevdata.i[dataNum] = data.i[dataNum]; 77 | data.i[dataNum] = value; 78 | } 79 | inline void SetUInt(int dataNum, uint32_t value) 80 | { 81 | prevdata.u[dataNum] = data.u[dataNum]; 82 | data.u[dataNum] = value; 83 | } 84 | inline void SetFloat(int dataNum, float value) 85 | { 86 | prevdata.f[dataNum] = data.f[dataNum]; 87 | data.f[dataNum] = value; 88 | } 89 | inline void SetPtr(int dataNum, void* ptr) 90 | { 91 | prevdata.iptr = data.iptr; 92 | data.iptr = (int*)ptr; 93 | } 94 | inline bool IsChanged() 95 | { 96 | for(uint8_t i = 0; i < count; ++i) { if(prevdata.i[i] != data.i[i]) return true; } 97 | return data.iptr != prevdata.iptr; 98 | } 99 | }; 100 | 101 | struct CustomUniform 102 | { 103 | int uniformId; 104 | bool needToApply; 105 | }; 106 | 107 | class ES3Shader : public ES2Shader 108 | { 109 | public: 110 | CustomUniform uniforms[CUSTOM_UNIFORMS]; 111 | 112 | //int uid_nShaderFlags; 113 | //int uid_fAngle; 114 | //int uid_nTime; 115 | //int uid_nGameTimeSeconds; 116 | //int uid_fUnderWaterness; 117 | //int uid_fRoadsWetness; 118 | //int uid_fFarClipDist; 119 | //int uid_nEntityModel; 120 | }; 121 | extern std::vector g_AllShaders; 122 | extern CustomStaticUniform staticUniforms[CUSTOM_UNIFORMS]; -------------------------------------------------------------------------------- /GTASA/files/shaders/fragment/blur.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | uniform sampler2D Diffuse; 3 | varying mediump vec2 Out_Tex0; 4 | varying mediump float Out_Z; 5 | uniform mediump vec4 RedGrade; 6 | uniform mediump vec4 GreenGrade; 7 | uniform mediump vec4 BlueGrade; 8 | 9 | void main() 10 | { 11 | vec4 color = texture2D(Diffuse, Out_Tex0) * 0.25; 12 | mediump vec2 dist = vec2(0.001, 0.001) * Out_Z; 13 | color += texture2D(Diffuse, Out_Tex0 + dist) * 0.175; 14 | color += texture2D(Diffuse, Out_Tex0 - dist) * 0.175; 15 | color += texture2D(Diffuse, Out_Tex0 + vec2(dist.x, -dist.y)) * 0.2; 16 | color += texture2D(Diffuse, Out_Tex0 + vec2(-dist.x, dist.y)) * 0.2; 17 | gl_FragColor.r = dot(color, RedGrade); 18 | gl_FragColor.g = dot(color, GreenGrade); 19 | gl_FragColor.b = dot(color, BlueGrade); 20 | } -------------------------------------------------------------------------------- /GTASA/files/shaders/fragment/contrast.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | uniform sampler2D Diffuse; 3 | varying mediump vec2 Out_Tex0; 4 | uniform mediump vec3 ContrastMult; 5 | uniform mediump vec3 ContrastAdd; 6 | 7 | void main() 8 | { 9 | gl_FragColor = texture2D(Diffuse, Out_Tex0); 10 | gl_FragColor.rgb *= ContrastMult; 11 | gl_FragColor.rgb += ContrastAdd; 12 | } -------------------------------------------------------------------------------- /GTASA/files/shaders/fragment/grading.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | uniform sampler2D Diffuse; 3 | varying mediump vec2 Out_Tex0; 4 | uniform mediump vec4 RedGrade; 5 | uniform mediump vec4 GreenGrade; 6 | uniform mediump vec4 BlueGrade; 7 | 8 | void main() 9 | { 10 | vec4 color = texture2D(Diffuse, Out_Tex0); 11 | gl_FragColor.r = dot(color, RedGrade); 12 | gl_FragColor.g = dot(color, GreenGrade); 13 | gl_FragColor.b = dot(color, BlueGrade); 14 | } -------------------------------------------------------------------------------- /GTASA/files/shaders/fragment/shadowResolve.glsl: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | uniform sampler2D Diffuse; 3 | varying mediump vec2 Out_Tex0; 4 | uniform mediump vec4 RedGrade; 5 | 6 | void main() 7 | { 8 | vec4 color = texture2D(Diffuse, Out_Tex0); 9 | gl_FragColor = vec4(0, 0, 0, (1.0 - color.r) * RedGrade.a); 10 | } -------------------------------------------------------------------------------- /GTASA/files/shaders/vertex/contrast.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | attribute vec3 Position; 3 | attribute vec2 TexCoord0; 4 | varying mediump vec2 Out_Tex0; 5 | varying mediump float Out_Z; 6 | 7 | void main() 8 | { 9 | gl_Position = vec4(Position.xy, 0.0, 1.0); 10 | Out_Z = Position.z; 11 | Out_Tex0 = TexCoord0; 12 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 AndroidModLoader 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### What am i? 2 | 3 | I am a shader loader for GTA:San Andreas! That's why my name is San Andreas Shader Loader (SAShaderL)! 4 | 5 | I am creating new uniforms for shaders such as: 6 | ``` 7 | uniform int ShaderFlags; // A flags for the shaders! Some shaders are using the same code! 8 | uniform vec3 SunVector; // A XYZ vector of the sun! 9 | uniform int Time; // Just a time (in milliseconds) 10 | uniform int GameTimeSeconds; // A clock time of the game in seconds! 01:02 AM is 62 seconds! 11 | uniform float UnderWaterness; // If the camera is underwater, this value is NOT 0! (**Values are between 0.0 and 1.0**) 12 | uniform float RoadsWetness; // Shows how much wet roads are. **Values are 0.0 - 1.0** 13 | uniform float FarClipDist; // Almost all the time it's 800.0, but not with the mods! 14 | uniform int EntityModel; // Model index of the last entity being draw (-1 if no model) 15 | ``` 16 | 17 | In a future i will be able to let mods create their own uniforms! 18 | 19 | Also it will allow to add uniforms with game variables through the config file! Easy peasy! 20 | 21 | Few things to notice: 22 | - Shader size is limited to 32 kilobytes -------------------------------------------------------------------------------- /isasl.h: -------------------------------------------------------------------------------- 1 | #ifndef _SA_SHADER_LOADER_H 2 | #define _SA_SHADER_LOADER_H 3 | 4 | #include 5 | 6 | enum eUniformValueType : uint8_t 7 | { 8 | UNIFORM_INT = 0, 9 | UNIFORM_UINT, 10 | UNIFORM_FLOAT, 11 | 12 | UNIFORM_MAXTYPES 13 | }; 14 | 15 | class ISASL 16 | { 17 | public: 18 | // 1 = Mod v1.1 19 | virtual int GetFeaturesVersion() = 0; 20 | 21 | // returns id for values setters 22 | // if has pointer, uses it's value 23 | virtual int RegisterUniform(const char* name, eUniformValueType type, uint8_t valuesArraySize, bool alwaysUpdate = false, void* pointer = NULL); 24 | 25 | virtual void SetUniformInt(int id, int dataNum, int value); 26 | virtual void SetUniformUInt(int id, int dataNum, uint32_t value); 27 | virtual void SetUniformFloat(int id, int dataNum, float value); 28 | virtual void SetUniformPtr(int id, int dataNum, void* ptr); 29 | virtual void ForceUpdateData(int id); 30 | }; 31 | 32 | #endif // _SA_SHADER_LOADER_H -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include "ES3Shader.h" 7 | 8 | //#define DUMP_SHADERS 9 | 10 | class SASL : public ISASL 11 | { 12 | public: 13 | inline void ResetApplyFlagForShaders(int customUniformId) 14 | { 15 | for(ES3Shader* shader : g_AllShaders) 16 | { 17 | shader->uniforms[customUniformId].needToApply = true; 18 | } 19 | } 20 | int GetFeaturesVersion() { return 1; } 21 | int RegisterUniform(const char* name, eUniformValueType type, uint8_t valuesArraySize, bool alwaysUpdate, void* pointer) 22 | { 23 | if(CustomStaticUniform::registeredUniforms >= CUSTOM_UNIFORMS) return -1; 24 | 25 | int id = CustomStaticUniform::registeredUniforms; 26 | staticUniforms[id].name = name; 27 | staticUniforms[id].count = valuesArraySize; 28 | staticUniforms[id].type = type; 29 | staticUniforms[id].alwaysUpdate = alwaysUpdate; 30 | staticUniforms[id].data.iptr = (int*)pointer; 31 | ++CustomStaticUniform::registeredUniforms; 32 | return id; 33 | } 34 | void SetUniformInt(int id, int dataNum, int value) 35 | { 36 | staticUniforms[id].SetInt(dataNum, value); 37 | if(staticUniforms[id].IsChanged()) ResetApplyFlagForShaders(id); 38 | } 39 | void SetUniformUInt(int id, int dataNum, uint32_t value) 40 | { 41 | staticUniforms[id].SetUInt(dataNum, value); 42 | if(staticUniforms[id].IsChanged()) ResetApplyFlagForShaders(id); 43 | } 44 | void SetUniformFloat(int id, int dataNum, float value) 45 | { 46 | staticUniforms[id].SetFloat(dataNum, value); 47 | if(staticUniforms[id].IsChanged()) ResetApplyFlagForShaders(id); 48 | } 49 | void SetUniformPtr(int id, int dataNum, void* ptr) 50 | { 51 | staticUniforms[id].SetPtr(dataNum, ptr); 52 | if(staticUniforms[id].IsChanged()) ResetApplyFlagForShaders(id); 53 | } 54 | void ForceUpdateData(int id) 55 | { 56 | ResetApplyFlagForShaders(id); 57 | } 58 | } sasl; 59 | 60 | MYMOD(net.rusjj.sashader, SAShaderLoader, 1.1, RusJJ) 61 | NEEDGAME(com.rockstargames.gtasa) 62 | 63 | // Savings 64 | #define SHADER_LEN (32 * 1024) // 32 kilobytes (4kb without patches) 65 | #define FRAGMENT_SHADER_STORAGE(__var1, __var2) sprintf(__var1, "%s/shaders/fragment/" #__var2 ".glsl", aml->GetAndroidDataPath()); 66 | #define VERTEX_SHADER_STORAGE(__var1, __var2) sprintf(__var1, "%s/shaders/vertex/" #__var2 ".glsl", aml->GetAndroidDataPath()); 67 | #define FRAGMENT_SHADER_GEN_STORAGE(__var1, __var2) sprintf(__var1, "%s/shaders/fragment/gen/%s.glsl", aml->GetAndroidDataPath(), __var2); 68 | #define VERTEX_SHADER_GEN_STORAGE(__var1, __var2) sprintf(__var1, "%s/shaders/vertex/gen/%s.glsl", aml->GetAndroidDataPath(), __var2); 69 | uintptr_t pGTASA; 70 | void *hGTASA, *hGLES; 71 | char blurShaderOwn[SHADER_LEN + 1], gradingShaderOwn[SHADER_LEN + 1], shadowResolveOwn[SHADER_LEN + 1], contrastVertexOwn[SHADER_LEN + 1], contrastFragmentOwn[SHADER_LEN + 1]; 72 | char customPixelShader[SHADER_LEN + 1], customVertexShader[SHADER_LEN + 1]; 73 | int lastModelId = -1; 74 | 75 | // Config 76 | 77 | 78 | // Game Vars 79 | const char **blurShader, **gradingShader, **shadowResolve, **contrastVertex, **contrastFragment; 80 | CVector *m_VectorToSun; 81 | int *m_CurrentStoredValue; 82 | uint32_t *m_snTimeInMilliseconds, *curShaderStateFlags; 83 | uint8_t *ms_nGameClockSeconds, *ms_nGameClockMinutes; 84 | float *UnderWaterness, *WetRoads; 85 | CCamera* TheCamera; 86 | ES3Shader** fragShaders; 87 | ES3Shader** activeShader; 88 | 89 | // Own Funcs 90 | inline void freadfull(char* buf, size_t maxlen, FILE *f) 91 | { 92 | size_t i = 0; 93 | --maxlen; 94 | while(!feof(f) && i 203 | inline void FlagToName(int flags, char (&out)[size]) 204 | { 205 | out[0] = 0; 206 | if(flags & FLAG_ALPHA_TEST) strlcat(out, "Atest", size); 207 | if(flags & FLAG_LIGHTING) strlcat(out, "Light", size); 208 | if(flags & FLAG_ALPHA_MODULATE) strlcat(out, "Mod", size); 209 | if(flags & FLAG_COLOR_EMISSIVE) strlcat(out, "Emiss", size); 210 | if(flags & FLAG_COLOR) strlcat(out, "Color", size); 211 | if(flags & FLAG_TEX0) strlcat(out, "T0", size); 212 | if(flags & FLAG_ENVMAP) strlcat(out, "Env", size); 213 | if(flags & FLAG_BONE3) strlcat(out, "B3", size); 214 | if(flags & FLAG_BONE4) strlcat(out, "B4", size); 215 | if(flags & FLAG_CAMERA_BASED_NORMALS) strlcat(out, "Norm", size); 216 | if(flags & FLAG_FOG) strlcat(out, "Fog", size); 217 | if(flags & FLAG_TEXBIAS) strlcat(out, "Bias", size); 218 | if(flags & FLAG_BACKLIGHT) strlcat(out, "Backl", size); 219 | if(flags & FLAG_LIGHT1) strlcat(out, "Light1", size); 220 | if(flags & FLAG_LIGHT2) strlcat(out, "Light2", size); 221 | if(flags & FLAG_LIGHT3) strlcat(out, "Light3", size); 222 | if(flags & FLAG_DETAILMAP) strlcat(out, "Detail", size); 223 | if(flags & FLAG_COMPRESSED_TEXCOORD) strlcat(out, "Comp", size); 224 | if(flags & FLAG_PROJECT_TEXCOORD) strlcat(out, "Proj", size); 225 | if(flags & FLAG_WATER) strlcat(out, "Water", size); 226 | if(flags & FLAG_COLOR2) strlcat(out, "Color2", size); 227 | if(flags & FLAG_SPHERE_XFORM) strlcat(out, "Xform", size); 228 | if(flags & FLAG_SPHERE_ENVMAP) strlcat(out, "Envmap", size); 229 | if(flags & FLAG_TEXMATRIX) strlcat(out, "Matrix", size); 230 | if(flags & FLAG_GAMMA) strlcat(out, "Gamma", size); 231 | 232 | if(flags & FLAG_CUSTOM_SKY) strlcat(out, "Sky", size); 233 | if(flags & FLAG_CUSTOM_BUILDING) strlcat(out, "Building", size); 234 | } 235 | 236 | // Game Funcs 237 | EmuShader* (*emu_CustomShaderCreate)(const char* fragShad, const char* vertShad); 238 | int (*_glGetUniformLocation)(int, const char*); 239 | void (*_glUniform1i)(int, int); 240 | void (*_glUniform1fv)(int, int, const float*); 241 | void (*_glUniform1iv)(int, int, const int*); 242 | void (*_glUniform1uiv)(int, int, const unsigned int*); 243 | DECL_HOOK(int, RQShaderBuildSource, int flags, char **pxlsrc, char **vtxsrc) 244 | { 245 | int ret = RQShaderBuildSource(flags, pxlsrc, vtxsrc); 246 | FILE *pFile; 247 | char szTmp[256], szNameCat[128]; 248 | FlagToName(flags, szNameCat); 249 | 250 | #ifdef DUMP_SHADERS 251 | const char* fragName = FlagsToShaderName(flags, false); 252 | if(fragName) 253 | { 254 | FRAGMENT_SHADER_GEN_STORAGE(szTmp, fragName); 255 | pFile = fopen(szTmp, "w"); 256 | if(pFile != NULL) 257 | { 258 | fwrite(*pxlsrc, 1, strlen(*pxlsrc), pFile); 259 | fclose(pFile); 260 | } 261 | } 262 | else 263 | { 264 | sprintf(szTmp, "%s/shaders/f/F_%s_0x%X.glsl", aml->GetAndroidDataPath(), szNameCat, flags); 265 | logger->Info(szTmp); 266 | pFile = fopen(szTmp, "w"); 267 | if(pFile != NULL) 268 | { 269 | fwrite(*pxlsrc, 1, strlen(*pxlsrc), pFile); 270 | fclose(pFile); 271 | } 272 | } 273 | 274 | const char* vertName = FlagsToShaderName(flags, true); 275 | if(vertName) 276 | { 277 | VERTEX_SHADER_GEN_STORAGE(szTmp, vertName); 278 | pFile = fopen(szTmp, "w"); 279 | if(pFile != NULL) 280 | { 281 | fwrite(*vtxsrc, 1, strlen(*vtxsrc), pFile); 282 | fclose(pFile); 283 | } 284 | } 285 | else 286 | { 287 | sprintf(szTmp, "%s/shaders/v/F_%s_0x%X.glsl", aml->GetAndroidDataPath(), szNameCat, flags); 288 | pFile = fopen(szTmp, "w"); 289 | if(pFile != NULL) 290 | { 291 | fwrite(*vtxsrc, 1, strlen(*vtxsrc), pFile); 292 | fclose(pFile); 293 | } 294 | } 295 | #else 296 | const char* fragName = FlagsToShaderName(flags, false); 297 | if(fragName) 298 | { 299 | FRAGMENT_SHADER_GEN_STORAGE(szTmp, fragName); 300 | pFile = fopen(szTmp, "r"); 301 | if(pFile != NULL) 302 | { 303 | logger->Info("Loading custom fragment shader \"%s\"", fragName); 304 | freadfull(*pxlsrc, SHADER_LEN, pFile); 305 | fclose(pFile); 306 | } 307 | } 308 | 309 | const char* vertName = FlagsToShaderName(flags, true); 310 | if(vertName) 311 | { 312 | VERTEX_SHADER_GEN_STORAGE(szTmp, vertName); 313 | pFile = fopen(szTmp, "r"); 314 | if(pFile != NULL) 315 | { 316 | logger->Info("Loading custom vertex shader \"%s\"", vertName); 317 | freadfull(*vtxsrc, SHADER_LEN, pFile); 318 | fclose(pFile); 319 | } 320 | } 321 | #endif 322 | 323 | return ret; 324 | } 325 | DECL_HOOKv(InitES2Shader, ES3Shader* self) 326 | { 327 | InitES2Shader(self); 328 | 329 | memset(self->uniforms, 0, sizeof(self->uniforms)); 330 | g_AllShaders.push_back(self); 331 | 332 | //self->uid_nShaderFlags = _glGetUniformLocation(self->nShaderId, "ShaderFlags"); 333 | //self->uid_fAngle = _glGetUniformLocation(self->nShaderId, "SunVector"); 334 | //self->uid_nTime = _glGetUniformLocation(self->nShaderId, "Time"); 335 | //self->uid_nGameTimeSeconds = _glGetUniformLocation(self->nShaderId, "GameTimeSeconds"); 336 | //self->uid_fUnderWaterness = _glGetUniformLocation(self->nShaderId, "UnderWaterness"); 337 | //self->uid_fRoadsWetness = _glGetUniformLocation(self->nShaderId, "RoadsWetness"); 338 | //self->uid_fFarClipDist = _glGetUniformLocation(self->nShaderId, "FarClipDist"); 339 | //self->uid_nEntityModel = _glGetUniformLocation(self->nShaderId, "EntityModel"); 340 | 341 | for(int i = 0; i < CustomStaticUniform::registeredUniforms; ++i) 342 | { 343 | self->uniforms[i].uniformId = _glGetUniformLocation(self->nShaderId, staticUniforms[i].name); 344 | } 345 | } 346 | DECL_HOOKv(RQ_Command_rqSelectShader, ES3Shader*** ptr) 347 | { 348 | ES3Shader* shader = **ptr; 349 | RQ_Command_rqSelectShader(ptr); 350 | 351 | //if(shader->uid_nShaderFlags >= 0) _glUniform1i(shader->uid_nShaderFlags, shader->flags); 352 | //if(shader->uid_fAngle >= 0) _glUniform1fv(shader->uid_fAngle, 3, &m_VectorToSun[*m_CurrentStoredValue].x); 353 | //if(shader->uid_nTime >= 0) _glUniform1i(shader->uid_nTime, *m_snTimeInMilliseconds); 354 | //if(shader->uid_nGameTimeSeconds >= 0) _glUniform1i(shader->uid_nGameTimeSeconds, (int)*ms_nGameClockMinutes * 60 + (int)*ms_nGameClockSeconds); 355 | //if(shader->uid_fUnderWaterness >= 0) _glUniform1fv(shader->uid_fUnderWaterness, 1, UnderWaterness); 356 | //if(shader->uid_fRoadsWetness >= 0) _glUniform1fv(shader->uid_fRoadsWetness, 1, WetRoads); 357 | //if(shader->uid_fFarClipDist >= 0 && TheCamera->m_pRwCamera != NULL) _glUniform1fv(shader->uid_fFarClipDist, 1, &TheCamera->m_pRwCamera->farClip); 358 | //if(shader->uid_nEntityModel >= 0) _glUniform1i(shader->uid_nEntityModel, lastModelId); 359 | 360 | for(int i = 0; i < CustomStaticUniform::registeredUniforms; ++i) 361 | { 362 | CustomUniform& uniform = shader->uniforms[i]; 363 | if(uniform.uniformId == -1) continue; 364 | 365 | CustomStaticUniform& staticUniform = staticUniforms[i]; 366 | if(staticUniform.alwaysUpdate || uniform.needToApply) 367 | { 368 | uniform.needToApply = false; 369 | switch(staticUniform.type) 370 | { 371 | case UNIFORM_INT: 372 | _glUniform1iv (uniform.uniformId, staticUniform.count, staticUniform.data.iptr ? staticUniform.data.iptr : &staticUniform.data.i[0]); 373 | break; 374 | case UNIFORM_UINT: 375 | _glUniform1uiv(uniform.uniformId, staticUniform.count, staticUniform.data.uptr ? staticUniform.data.uptr : &staticUniform.data.u[0]); 376 | break; 377 | case UNIFORM_FLOAT: 378 | _glUniform1fv (uniform.uniformId, staticUniform.count, staticUniform.data.fptr ? staticUniform.data.fptr : &staticUniform.data.f[0]); 379 | break; 380 | default: 381 | break; 382 | } 383 | } 384 | } 385 | } 386 | DECL_HOOKv(RenderSkyPolys) 387 | { 388 | *curShaderStateFlags |= FLAG_CUSTOM_SKY; 389 | RenderSkyPolys(); 390 | *curShaderStateFlags &= ~FLAG_CUSTOM_SKY; 391 | } 392 | DECL_HOOKv(OnEntityRender, CEntity* self) 393 | { 394 | lastModelId = self->m_nModelIndex; 395 | if(self->m_nType == ENTITY_TYPE_BUILDING) 396 | { 397 | *curShaderStateFlags |= FLAG_CUSTOM_BUILDING; 398 | OnEntityRender(self); 399 | *curShaderStateFlags &= ~FLAG_CUSTOM_BUILDING; 400 | lastModelId = -1; 401 | return; 402 | } 403 | OnEntityRender(self); 404 | lastModelId = -1; 405 | } 406 | 407 | // Patch funcs 408 | #ifdef AML32 409 | uintptr_t BuildShader_BackTo; 410 | __attribute__((optnone)) __attribute__((naked)) void BuildShader_inject(void) 411 | { 412 | asm volatile( 413 | "MOV R5, R0\n" 414 | "MOV R8, R2\n"); 415 | asm volatile( 416 | "MOV R0, %0\n" 417 | :: "r" (sizeof(ES3Shader))); 418 | asm volatile( 419 | "PUSH {R0}\n"); 420 | asm volatile( 421 | "MOV R12, %0\n" 422 | "POP {R0}\n" 423 | "BX R12\n" 424 | :: "r" (BuildShader_BackTo)); 425 | } 426 | #else 427 | inline void ReplaceADRL(uintptr_t addr, uint32_t firstVal, uint32_t secVal) 428 | { 429 | aml->Write32(addr, firstVal); 430 | aml->Write32(addr + 0x4, secVal); 431 | } 432 | #endif 433 | 434 | // int main! 435 | extern "C" void OnModPreLoad() 436 | { 437 | sasl.RegisterUniform("Time", UNIFORM_UINT, 1, true, m_snTimeInMilliseconds); 438 | sasl.RegisterUniform("UnderWaterness", UNIFORM_FLOAT, 1, true, UnderWaterness); 439 | 440 | RegisterInterface("SASL", &sasl); 441 | } 442 | extern "C" void OnModLoad() 443 | { 444 | logger->SetTag("SA ShaderLoader"); 445 | 446 | pGTASA = aml->GetLib("libGTASA.so"); 447 | hGTASA = aml->GetLibHandle("libGTASA.so"); 448 | if(!pGTASA || !hGTASA) 449 | { 450 | logger->Error("GTA:SA is not loaded :o"); 451 | return; 452 | } 453 | 454 | hGLES = aml->GetLibHandle("libGLESv2.so"); 455 | if(!hGLES) 456 | { 457 | logger->Error("Open GLES is not loaded :o"); 458 | return; 459 | } 460 | 461 | SET_TO(blurShader, aml->GetSym(hGTASA, "blurPShader")); 462 | SET_TO(gradingShader, aml->GetSym(hGTASA, "gradingPShader")); 463 | SET_TO(shadowResolve, aml->GetSym(hGTASA, "shadowResolvePShader")); 464 | SET_TO(contrastVertex, aml->GetSym(hGTASA, "contrastVShader")); 465 | SET_TO(contrastFragment, aml->GetSym(hGTASA, "contrastPShader")); 466 | 467 | // Other shaders (unstable as hell!) 468 | HOOKPLT(RQShaderBuildSource, pGTASA + BYBIT(0x6720F8, 0x8439A0)); 469 | 470 | FILE *pFile; 471 | char szTmp[256]; 472 | 473 | FRAGMENT_SHADER_STORAGE(szTmp, blur); 474 | if((pFile = fopen(szTmp, "r"))!=NULL) 475 | { 476 | freadfull(blurShaderOwn, SHADER_LEN, pFile); 477 | *blurShader = blurShaderOwn; 478 | fclose(pFile); 479 | } 480 | 481 | FRAGMENT_SHADER_STORAGE(szTmp, grading); 482 | if((pFile = fopen(szTmp, "r"))!=NULL) 483 | { 484 | freadfull(gradingShaderOwn, SHADER_LEN, pFile); 485 | *gradingShader = gradingShaderOwn; 486 | fclose(pFile); 487 | } 488 | 489 | FRAGMENT_SHADER_STORAGE(szTmp, shadowResolve); 490 | if((pFile = fopen(szTmp, "r"))!=NULL) 491 | { 492 | freadfull(shadowResolveOwn, SHADER_LEN, pFile); 493 | *shadowResolve = shadowResolveOwn; 494 | fclose(pFile); 495 | } 496 | 497 | VERTEX_SHADER_STORAGE(szTmp, contrast); 498 | if((pFile = fopen(szTmp, "r"))!=NULL) 499 | { 500 | freadfull(contrastVertexOwn, SHADER_LEN, pFile); 501 | *contrastVertex = contrastVertexOwn; 502 | fclose(pFile); 503 | } 504 | 505 | FRAGMENT_SHADER_STORAGE(szTmp, contrast); 506 | if((pFile = fopen(szTmp, "r"))!=NULL) 507 | { 508 | freadfull(contrastFragmentOwn, SHADER_LEN, pFile); 509 | *contrastFragment = contrastFragmentOwn; 510 | fclose(pFile); 511 | } 512 | 513 | #ifdef AML32 514 | BuildShader_BackTo = pGTASA + 0x1CD838 + 0x1; 515 | aml->Redirect(pGTASA + 0x1CD830 + 0x1, (uintptr_t)BuildShader_inject); 516 | #else 517 | aml->Write32(pGTASA + 0x262AB0, MOVBits::Create(sizeof(ES3Shader), 0, false)); 518 | #endif 519 | 520 | #ifdef AML32 521 | HOOKPLT(InitES2Shader, pGTASA + 0x671BDC); 522 | HOOKPLT(RQ_Command_rqSelectShader, pGTASA + 0x67632C);//aml->GetSym(hGTASA, "_Z25RQ_Command_rqSelectShaderRPc")); 523 | HOOKPLT(RenderSkyPolys, pGTASA + 0x670A7C); 524 | HOOK(OnEntityRender, aml->GetSym(hGTASA, "_ZN7CEntity6RenderEv")); 525 | #else 526 | HOOKBL(InitES2Shader, pGTASA + 0x26213C); 527 | HOOKPLT(RQ_Command_rqSelectShader, pGTASA + 0x84A6B0);//aml->GetSym(hGTASA, "_Z25RQ_Command_rqSelectShaderRPc")); 528 | HOOKPLT(RenderSkyPolys, pGTASA + 0x8414C8); 529 | HOOK(OnEntityRender, aml->GetSym(hGTASA, "_ZN7CEntity6RenderEv")); 530 | #endif 531 | 532 | SET_TO(_glGetUniformLocation, *(void**)(pGTASA + BYBIT(0x6755EC, 0x8403B0))); 533 | SET_TO(_glUniform1i, *(void**)(pGTASA + BYBIT(0x674484, 0x846858))); 534 | SET_TO(_glUniform1fv, *(void**)(pGTASA + BYBIT(0x672388, 0x845048))); 535 | SET_TO(emu_CustomShaderCreate, aml->GetSym(hGTASA, "_Z22emu_CustomShaderCreatePKcS0_")); 536 | SET_TO(_glUniform1iv, aml->GetSym(hGLES, "glUniform1iv")); 537 | SET_TO(_glUniform1uiv, aml->GetSym(hGLES, "glUniform1uiv")); 538 | 539 | SET_TO(fragShaders, pGTASA + BYBIT(0x6B408C, 0x891058)); 540 | SET_TO(activeShader, aml->GetSym(hGTASA, "_ZN9ES2Shader12activeShaderE")); 541 | SET_TO(m_VectorToSun, aml->GetSym(hGTASA, "_ZN10CTimeCycle13m_VectorToSunE")); 542 | SET_TO(m_CurrentStoredValue, aml->GetSym(hGTASA, "_ZN10CTimeCycle20m_CurrentStoredValueE")); 543 | SET_TO(m_snTimeInMilliseconds, aml->GetSym(hGTASA, "_ZN6CTimer22m_snTimeInMillisecondsE")); 544 | SET_TO(curShaderStateFlags, aml->GetSym(hGTASA, "curShaderStateFlags")); 545 | SET_TO(ms_nGameClockMinutes, aml->GetSym(hGTASA, "_ZN6CClock20ms_nGameClockMinutesE")); 546 | SET_TO(ms_nGameClockSeconds, aml->GetSym(hGTASA, "_ZN6CClock20ms_nGameClockSecondsE")); 547 | SET_TO(UnderWaterness, aml->GetSym(hGTASA, "_ZN8CWeather14UnderWaternessE")); 548 | SET_TO(WetRoads, aml->GetSym(hGTASA, "_ZN8CWeather8WetRoadsE")); 549 | SET_TO(TheCamera, aml->GetSym(hGTASA, "TheCamera")); 550 | 551 | #ifdef AML32 552 | aml->WriteAddr(pGTASA + 0x1CF73C, (uintptr_t)&customVertexShader - pGTASA - 0x1CEA48); 553 | aml->WriteAddr(pGTASA + 0x1CF7AC, (uintptr_t)&customVertexShader - pGTASA - 0x1CEAD0); 554 | aml->WriteAddr(pGTASA + 0x1CF7C0, (uintptr_t)&customVertexShader - pGTASA - 0x1CEB44); 555 | aml->WriteAddr(pGTASA + 0x1CF7CC, (uintptr_t)&customVertexShader - pGTASA - 0x1CEB8C); 556 | aml->WriteAddr(pGTASA + 0x1CF7D4, (uintptr_t)&customVertexShader - pGTASA - 0x1CEBB0); 557 | aml->WriteAddr(pGTASA + 0x1CF7E0, (uintptr_t)&customVertexShader - pGTASA - 0x1CEBF0); 558 | aml->WriteAddr(pGTASA + 0x1CF7EC, (uintptr_t)&customVertexShader - pGTASA - 0x1CEC2A); 559 | aml->WriteAddr(pGTASA + 0x1CF80C, (uintptr_t)&customVertexShader - pGTASA - 0x1CEC86); 560 | aml->WriteAddr(pGTASA + 0x1CF814, (uintptr_t)&customVertexShader - pGTASA - 0x1CEC6C); 561 | aml->WriteAddr(pGTASA + 0x1CF81C, (uintptr_t)&customVertexShader - pGTASA - 0x1CECA6); 562 | aml->WriteAddr(pGTASA + 0x1CF824, (uintptr_t)&customVertexShader - pGTASA - 0x1CECCC); 563 | aml->WriteAddr(pGTASA + 0x1CF838, (uintptr_t)&customVertexShader - pGTASA - 0x1CED30); 564 | aml->WriteAddr(pGTASA + 0x1CF840, (uintptr_t)&customVertexShader - pGTASA - 0x1CED58); 565 | aml->WriteAddr(pGTASA + 0x1CF848, (uintptr_t)&customVertexShader - pGTASA - 0x1CEDA2); 566 | aml->WriteAddr(pGTASA + 0x1CF850, (uintptr_t)&customVertexShader - pGTASA - 0x1CED88); 567 | aml->WriteAddr(pGTASA + 0x1CF858, (uintptr_t)&customVertexShader - pGTASA - 0x1CEDC2); 568 | aml->WriteAddr(pGTASA + 0x1CF860, (uintptr_t)&customVertexShader - pGTASA - 0x1CEDEE); 569 | aml->WriteAddr(pGTASA + 0x1CF868, (uintptr_t)&customVertexShader - pGTASA - 0x1CEE14); 570 | aml->WriteAddr(pGTASA + 0x1CF874, (uintptr_t)&customVertexShader - pGTASA - 0x1CEE56); 571 | aml->WriteAddr(pGTASA + 0x1CF888, (uintptr_t)&customVertexShader - pGTASA - 0x1CEECC); 572 | aml->WriteAddr(pGTASA + 0x1CF894, (uintptr_t)&customVertexShader - pGTASA - 0x1CEF0E); 573 | aml->WriteAddr(pGTASA + 0x1CF89C, (uintptr_t)&customVertexShader - pGTASA - 0x1CEF46); 574 | aml->WriteAddr(pGTASA + 0x1CF8A4, (uintptr_t)&customVertexShader - pGTASA - 0x1CEF64); 575 | aml->WriteAddr(pGTASA + 0x1CF8AC, (uintptr_t)&customVertexShader - pGTASA - 0x1CF146); 576 | aml->WriteAddr(pGTASA + 0x1CF8B4, (uintptr_t)&customVertexShader - pGTASA - 0x1CEF8C); 577 | aml->WriteAddr(pGTASA + 0x1CF8E8, (uintptr_t)&customVertexShader - pGTASA - 0x1CF0D2); 578 | aml->WriteAddr(pGTASA + 0x1CF8F8, (uintptr_t)&customVertexShader - pGTASA - 0x1CF126); 579 | aml->WriteAddr(pGTASA + 0x1CF900, (uintptr_t)&customVertexShader - pGTASA - 0x1CF198); 580 | aml->WriteAddr(pGTASA + 0x1CF914, (uintptr_t)&customVertexShader - pGTASA - 0x1CF170); 581 | aml->WriteAddr(pGTASA + 0x1CF920, (uintptr_t)&customVertexShader - pGTASA - 0x1CF23C); 582 | aml->WriteAddr(pGTASA + 0x1CF928, (uintptr_t)&customVertexShader - pGTASA - 0x1CF21C); 583 | aml->WriteAddr(pGTASA + 0x1CF930, (uintptr_t)&customVertexShader - pGTASA - 0x1CF274); 584 | aml->WriteAddr(pGTASA + 0x1CF938, (uintptr_t)&customVertexShader - pGTASA - 0x1CF25A); 585 | aml->WriteAddr(pGTASA + 0x1CF944, (uintptr_t)&customVertexShader - pGTASA - 0x1CF2A4); 586 | aml->WriteAddr(pGTASA + 0x1CF958, (uintptr_t)&customVertexShader - pGTASA - 0x1CF314); 587 | aml->WriteAddr(pGTASA + 0x1CF960, (uintptr_t)&customVertexShader - pGTASA - 0x1CF2F8); 588 | aml->WriteAddr(pGTASA + 0x1CF968, (uintptr_t)&customVertexShader - pGTASA - 0x1CF33A); 589 | aml->WriteAddr(pGTASA + 0x1CF974, (uintptr_t)&customVertexShader - pGTASA - 0x1CF392); 590 | aml->WriteAddr(pGTASA + 0x1CF97C, (uintptr_t)&customVertexShader - pGTASA - 0x1CF378); 591 | aml->WriteAddr(pGTASA + 0x1CF988, (uintptr_t)&customVertexShader - pGTASA - 0x1CF3B6); 592 | aml->WriteAddr(pGTASA + 0x1CF994, (uintptr_t)&customVertexShader - pGTASA - 0x1CF3FA); 593 | aml->WriteAddr(pGTASA + 0x1CF99C, (uintptr_t)&customVertexShader - pGTASA - 0x1CF458); 594 | aml->WriteAddr(pGTASA + 0x1CF9A4, (uintptr_t)&customVertexShader - pGTASA - 0x1CF43E); 595 | aml->WriteAddr(pGTASA + 0x1CF9AC, (uintptr_t)&customVertexShader - pGTASA - 0x1CF41C); 596 | aml->WriteAddr(pGTASA + 0x1CF9B4, (uintptr_t)&customVertexShader - pGTASA - 0x1CF516); 597 | aml->WriteAddr(pGTASA + 0x1CF9BC, (uintptr_t)&customVertexShader - pGTASA - 0x1CF6F6); 598 | aml->WriteAddr(pGTASA + 0x1CF9C4, (uintptr_t)&customVertexShader - pGTASA - 0x1CF71A); 599 | aml->WriteAddr(pGTASA + 0x1CF9CC, (uintptr_t)&customVertexShader - pGTASA - 0x1CF492); 600 | aml->WriteAddr(pGTASA + 0x1CF9D4, (uintptr_t)&customVertexShader - pGTASA - 0x1CF4E6); 601 | aml->WriteAddr(pGTASA + 0x1CF9DC, (uintptr_t)&customVertexShader - pGTASA - 0x1CF534); 602 | aml->WriteAddr(pGTASA + 0x1CF9E4, (uintptr_t)&customVertexShader - pGTASA - 0x1CF4C4); 603 | aml->WriteAddr(pGTASA + 0x1CF9EC, (uintptr_t)&customVertexShader - pGTASA - 0x1CF554); 604 | aml->WriteAddr(pGTASA + 0x1CF9F8, (uintptr_t)&customVertexShader - pGTASA - 0x1CF5EA); 605 | aml->WriteAddr(pGTASA + 0x1CFA14, (uintptr_t)&customVertexShader - pGTASA - 0x1CF5AC); 606 | aml->WriteAddr(pGTASA + 0x1CFA20, (uintptr_t)&customVertexShader - pGTASA - 0x1CF674); 607 | aml->WriteAddr(pGTASA + 0x1CFA30, (uintptr_t)&customVertexShader - pGTASA - 0x1CF6BE); 608 | aml->WriteAddr(pGTASA + 0x1CFA78, (uintptr_t)&customVertexShader - pGTASA - 0x1CFA50); 609 | 610 | aml->WriteAddr(pGTASA + 0x1CE834, (uintptr_t)&customPixelShader - pGTASA - 0x1CE192); 611 | aml->WriteAddr(pGTASA + 0x1CE854, (uintptr_t)&customPixelShader - pGTASA - 0x1CE1B6); 612 | aml->WriteAddr(pGTASA + 0x1CE878, (uintptr_t)&customPixelShader - pGTASA - 0x1CE1FC); 613 | aml->WriteAddr(pGTASA + 0x1CE884, (uintptr_t)&customPixelShader - pGTASA - 0x1CE288); 614 | aml->WriteAddr(pGTASA + 0x1CE88C, (uintptr_t)&customPixelShader - pGTASA - 0x1CE238); 615 | aml->WriteAddr(pGTASA + 0x1CE890, (uintptr_t)&customPixelShader - pGTASA - 0x1CE256); 616 | aml->WriteAddr(pGTASA + 0x1CE8B4, (uintptr_t)&customPixelShader - pGTASA - 0x1CE2B0); 617 | aml->WriteAddr(pGTASA + 0x1CE8D8, (uintptr_t)&customPixelShader - pGTASA - 0x1CE2EE); 618 | aml->WriteAddr(pGTASA + 0x1CE8E0, (uintptr_t)&customPixelShader - pGTASA - 0x1CE322); 619 | aml->WriteAddr(pGTASA + 0x1CE8E8, (uintptr_t)&customPixelShader - pGTASA - 0x1CE346); 620 | aml->WriteAddr(pGTASA + 0x1CE8F0, (uintptr_t)&customPixelShader - pGTASA - 0x1CE36A); 621 | aml->WriteAddr(pGTASA + 0x1CE900, (uintptr_t)&customPixelShader - pGTASA - 0x1CE3BE); 622 | aml->WriteAddr(pGTASA + 0x1CE910, (uintptr_t)&customPixelShader - pGTASA - 0x1CE446); 623 | aml->WriteAddr(pGTASA + 0x1CE918, (uintptr_t)&customPixelShader - pGTASA - 0x1CE47A); 624 | aml->WriteAddr(pGTASA + 0x1CE928, (uintptr_t)&customPixelShader - pGTASA - 0x1CE460); 625 | aml->WriteAddr(pGTASA + 0x1CE934, (uintptr_t)&customPixelShader - pGTASA - 0x1CE426); 626 | aml->WriteAddr(pGTASA + 0x1CE93C, (uintptr_t)&customPixelShader - pGTASA - 0x1CE4B8); 627 | aml->WriteAddr(pGTASA + 0x1CE944, (uintptr_t)&customPixelShader - pGTASA - 0x1CE4D8); 628 | aml->WriteAddr(pGTASA + 0x1CE94C, (uintptr_t)&customPixelShader - pGTASA - 0x1CE582); 629 | aml->WriteAddr(pGTASA + 0x1CE954, (uintptr_t)&customPixelShader - pGTASA - 0x1CE530); 630 | aml->WriteAddr(pGTASA + 0x1CE960, (uintptr_t)&customPixelShader - pGTASA - 0x1CE500); 631 | aml->WriteAddr(pGTASA + 0x1CE968, (uintptr_t)&customPixelShader - pGTASA - 0x1CE568); 632 | aml->WriteAddr(pGTASA + 0x1CE970, (uintptr_t)&customPixelShader - pGTASA - 0x1CE5A4); 633 | aml->WriteAddr(pGTASA + 0x1CE978, (uintptr_t)&customPixelShader - pGTASA - 0x1CE5C8); 634 | aml->WriteAddr(pGTASA + 0x1CE994, (uintptr_t)&customPixelShader - pGTASA - 0x1CE65E); 635 | aml->WriteAddr(pGTASA + 0x1CE9A0, (uintptr_t)&customPixelShader - pGTASA - 0x1CE686); 636 | aml->WriteAddr(pGTASA + 0x1CE9A8, (uintptr_t)&customPixelShader - pGTASA - 0x1CE6A4); 637 | aml->WriteAddr(pGTASA + 0x1CE9B0, (uintptr_t)&customPixelShader - pGTASA - 0x1CE6BE); 638 | aml->WriteAddr(pGTASA + 0x1CE9B8, (uintptr_t)&customPixelShader - pGTASA - 0x1CE6DC); 639 | aml->WriteAddr(pGTASA + 0x1CE9C0, (uintptr_t)&customPixelShader - pGTASA - 0x1CE750); 640 | aml->WriteAddr(pGTASA + 0x1CE9C8, (uintptr_t)&customPixelShader - pGTASA - 0x1CE78A); 641 | aml->WriteAddr(pGTASA + 0x1CE9D4, (uintptr_t)&customPixelShader - pGTASA - 0x1CE708); 642 | aml->WriteAddr(pGTASA + 0x1CE9DC, (uintptr_t)&customPixelShader - pGTASA - 0x1CE73A); 643 | aml->WriteAddr(pGTASA + 0x1CE9E4, (uintptr_t)&customPixelShader - pGTASA - 0x1CE768); 644 | aml->WriteAddr(pGTASA + 0x1CE9F0, (uintptr_t)&customPixelShader - pGTASA - 0x1CE724); 645 | aml->WriteAddr(pGTASA + 0x1CE9F8, (uintptr_t)&customPixelShader - pGTASA - 0x1CE7BE); 646 | aml->WriteAddr(pGTASA + 0x1CEA00, (uintptr_t)&customPixelShader - pGTASA - 0x1CE7DE); 647 | aml->WriteAddr(pGTASA + 0x1CEA08, (uintptr_t)&customPixelShader - pGTASA - 0x1CE7F6); 648 | aml->WriteAddr(pGTASA + 0x1CFA7C, (uintptr_t)&customPixelShader - pGTASA - 0x1CFA54); 649 | #else 650 | aml->WriteAddr(pGTASA + 0x89A198, &customVertexShader); 651 | aml->Write32(pGTASA + 0x264C64, 0xD00031B7); 652 | aml->Write32(pGTASA + 0x264C6C, 0xF940CEF7); 653 | ReplaceADRL(pGTASA + 0x263DBC + 0x44, 0xF00031B4, 0xF940CE94); 654 | ReplaceADRL(pGTASA + 0x263DBC + 0xF0, 0xF00031B4, 0xF940CE94); 655 | ReplaceADRL(pGTASA + 0x263DBC + 0x17C, 0xF00031B4, 0xF940CE94); 656 | ReplaceADRL(pGTASA + 0x263DBC + 0x1DC, 0xF00031A0, 0xF940CC00); 657 | ReplaceADRL(pGTASA + 0x263DBC + 0x204, 0xF00031B4, 0xF940CE94); 658 | ReplaceADRL(pGTASA + 0x263DBC + 0x250, 0xD00031B4, 0xF940CE94); 659 | ReplaceADRL(pGTASA + 0x263DBC + 0x298, 0xD00031B4, 0xF940CE94); 660 | ReplaceADRL(pGTASA + 0x263DBC + 0x2F4, 0xD00031A0, 0xF940CC00); 661 | ReplaceADRL(pGTASA + 0x263DBC + 0x318, 0xD00031A0, 0xF940CC00); 662 | ReplaceADRL(pGTASA + 0x263DBC + 0x344, 0xD00031B4, 0xF940CE94); 663 | ReplaceADRL(pGTASA + 0x263DBC + 0x3C0, 0xD00031A0, 0xF940CC00); 664 | ReplaceADRL(pGTASA + 0x263DBC + 0x3E8, 0xD00031A0, 0xF940CC00); 665 | ReplaceADRL(pGTASA + 0x263DBC + 0x42C, 0xD00031A0, 0xF940CC00); 666 | ReplaceADRL(pGTASA + 0x263DBC + 0x450, 0xD00031A0, 0xF940CC00); 667 | ReplaceADRL(pGTASA + 0x263DBC + 0x484, 0xD00031A0, 0xF940CC00); 668 | ReplaceADRL(pGTASA + 0x263DBC + 0x4B4, 0xD00031B4, 0xF940CE94); 669 | ReplaceADRL(pGTASA + 0x263DBC + 0x508, 0xD00031A0, 0xF940CC00); 670 | ReplaceADRL(pGTASA + 0x263DBC + 0x544, 0xD00031A0, 0xF940CC00); 671 | ReplaceADRL(pGTASA + 0x263DBC + 0x568, 0xD00031A0, 0xF940CC00); 672 | ReplaceADRL(pGTASA + 0x263DBC + 0x590, 0xD00031B4, 0xF940CE94); 673 | ReplaceADRL(pGTASA + 0x263DBC + 0x71C, 0xD00031B4, 0xF940CE94); 674 | ReplaceADRL(pGTASA + 0x263DBC + 0x790, 0xD00031B4, 0xF940CE94); 675 | ReplaceADRL(pGTASA + 0x263DBC + 0x7DC, 0xD00031B4, 0xF940CE94); 676 | ReplaceADRL(pGTASA + 0x263DBC + 0x86C, 0xD00031A0, 0xF940CC00); 677 | ReplaceADRL(pGTASA + 0x263DBC + 0x894, 0xD00031B4, 0xF940CE94); 678 | ReplaceADRL(pGTASA + 0x263DBC + 0x8C8, 0xD00031B4, 0xF940CE94); 679 | ReplaceADRL(pGTASA + 0x263DBC + 0x998, 0xD00031A0, 0xF940CC00); 680 | ReplaceADRL(pGTASA + 0x263DBC + 0x9D0, 0xD00031A0, 0xF940CC00); 681 | ReplaceADRL(pGTASA + 0x263DBC + 0xA40, 0xD00031A0, 0xF940CC00); 682 | ReplaceADRL(pGTASA + 0x263DBC + 0xA68, 0xD00031B4, 0xF940CE94); 683 | ReplaceADRL(pGTASA + 0x263DBC + 0xAC0, 0xD00031A0, 0xF940CC00); 684 | ReplaceADRL(pGTASA + 0x263DBC + 0xAE8, 0xD00031A0, 0xF940CC00); 685 | ReplaceADRL(pGTASA + 0x263DBC + 0xB38, 0xD00031A0, 0xF940CC00); 686 | ReplaceADRL(pGTASA + 0x263DBC + 0xB8C, 0xD00031A0, 0xF940CC00); 687 | ReplaceADRL(pGTASA + 0x263DBC + 0xBC4, 0xD00031A0, 0xF940CC00); 688 | ReplaceADRL(pGTASA + 0x263DBC + 0xC58, 0xD00031A0, 0xF940CC00); 689 | ReplaceADRL(pGTASA + 0x263DBC + 0xC7C, 0xD00031A0, 0xF940CC00); 690 | ReplaceADRL(pGTASA + 0x263DBC + 0xCCC, 0xD00031B4, 0xF940CE94); 691 | ReplaceADRL(pGTASA + 0x263DBC + 0xCF0, 0xD00031B4, 0xF940CE94); 692 | ReplaceADRL(pGTASA + 0x263DBC + 0xD90, 0xD00031B3, 0xF940CE73); 693 | ReplaceADRL(pGTASA + 0x263DBC + 0xDF8, 0xD00031A0, 0xF940CC00); 694 | ReplaceADRL(pGTASA + 0x263DBC + 0xE4C, 0xD00031A0, 0xF940CC00); 695 | ReplaceADRL(pGTASA + 0x263DBC + 0xE74, 0xD00031A0, 0xF940CC00); 696 | 697 | aml->WriteAddr(pGTASA + 0x898190, &customPixelShader); 698 | aml->Write32(pGTASA + 0x264C60, 0x900031B6); 699 | aml->Write32(pGTASA + 0x264C68, 0xF940CAD6); 700 | ReplaceADRL(pGTASA + 0x263618 + 0x48, 0xB00031A0, 0xF940C800); 701 | ReplaceADRL(pGTASA + 0x263618 + 0x70, 0xB00031B5, 0xF940CAB5); 702 | ReplaceADRL(pGTASA + 0x263618 + 0xC8, 0xB00031B5, 0xF940CAB5); 703 | ReplaceADRL(pGTASA + 0x263618 + 0x124, 0xB00031B5, 0xF940CAB5); 704 | ReplaceADRL(pGTASA + 0x263618 + 0x16C, 0xB00031A0, 0xF940C800); 705 | ReplaceADRL(pGTASA + 0x263618 + 0x194, 0xB00031B5, 0xF940CAB5); 706 | ReplaceADRL(pGTASA + 0x263618 + 0x1E8, 0xB00031A0, 0xF940C800); 707 | ReplaceADRL(pGTASA + 0x263618 + 0x21C, 0xB00031A0, 0xF940C800); 708 | ReplaceADRL(pGTASA + 0x263618 + 0x244, 0xB00031A0, 0xF940C800); 709 | ReplaceADRL(pGTASA + 0x263618 + 0x26C, 0xB00031B5, 0xF940CAB5); 710 | ReplaceADRL(pGTASA + 0x263618 + 0x2D4, 0xB00031B5, 0xF940CAB5); 711 | ReplaceADRL(pGTASA + 0x263618 + 0x388, 0xB00031A0, 0xF940C800); 712 | ReplaceADRL(pGTASA + 0x263618 + 0x3AC, 0xB00031A0, 0xF940C800); 713 | ReplaceADRL(pGTASA + 0x263618 + 0x3D8, 0xB00031A0, 0xF940C800); 714 | ReplaceADRL(pGTASA + 0x263618 + 0x40C, 0xB00031B5, 0xF940CAB5); 715 | ReplaceADRL(pGTASA + 0x263618 + 0x460, 0xB00031A0, 0xF940C800); 716 | ReplaceADRL(pGTASA + 0x263618 + 0x488, 0xB00031A0, 0xF940C800); 717 | ReplaceADRL(pGTASA + 0x263618 + 0x4B0, 0xB00031B5, 0xF940CAB5); 718 | ReplaceADRL(pGTASA + 0x263618 + 0x570, 0xB00031A0, 0xF940C800); 719 | ReplaceADRL(pGTASA + 0x263618 + 0x5A0, 0xB00031A0, 0xF940C800); 720 | ReplaceADRL(pGTASA + 0x263618 + 0x5C8, 0xB00031A0, 0xF940C800); 721 | ReplaceADRL(pGTASA + 0x263618 + 0x5EC, 0xB00031A0, 0xF940C800); 722 | ReplaceADRL(pGTASA + 0x263618 + 0x614, 0xB00031A0, 0xF940C800); 723 | ReplaceADRL(pGTASA + 0x263618 + 0x678, 0xB00031A0, 0xF940C800); 724 | ReplaceADRL(pGTASA + 0x263618 + 0x69C, 0xB00031B4, 0xF940CA94); 725 | ReplaceADRL(pGTASA + 0x263618 + 0x6D0, 0xB00031B4, 0xF940CA94); 726 | ReplaceADRL(pGTASA + 0x263618 + 0x718, 0xB00031A0, 0xF940C800); 727 | ReplaceADRL(pGTASA + 0x263618 + 0x740, 0xB00031A0, 0xF940C800); 728 | ReplaceADRL(pGTASA + 0x263618 + 0x764, 0xB00031A0, 0xF940C800); 729 | #endif 730 | 731 | memset(staticUniforms, 0, sizeof(staticUniforms)); 732 | for(int i = 0; i < CUSTOM_UNIFORMS; ++i) 733 | { 734 | staticUniforms[i].id = i; 735 | } 736 | } 737 | 738 | int CustomStaticUniform::registeredUniforms = 0; 739 | CustomStaticUniform staticUniforms[CUSTOM_UNIFORMS]; 740 | std::vector g_AllShaders; --------------------------------------------------------------------------------