Skip to content

Instantly share code, notes, and snippets.

@pepoluan
Last active December 16, 2023 21:22
Show Gist options
  • Save pepoluan/f64b2ac12ea286955340 to your computer and use it in GitHub Desktop.
Save pepoluan/f64b2ac12ea286955340 to your computer and use it in GitHub Desktop.
NFSU2 + TexMod Loader, also sets CPU Affinity
; The purpose of this script is to start Need for Speed: Underground 2 (NFSU2) from TexMod, after loading a
; texture replacement package (TPF). This script also sets CPU Affinity of NFSU2's SPEED2.EXE, because SPEED2.EXE
; is not happy with a multicore processor; it wants to stay on one core and one core only.
#Include <Affinity_Set>
; Affinity_Set() is a function from affinity.ahk, which should be placed in
; a lib/ subdirectory (from where this script is located)
; My version was from https://github.com/dufferzafar/Autohotkey-Scripts/blob/master/lib/Affinity.ahk
; ===== TUNABLES =====
NFSU_Dir = D:\Games\NFSU2
Speed_exe = SPEED2.EXE
TexMod_Dir = D:\Games\NFSU2\Texmod
TexMod_exe = Texmod.exe
; Assume .tpf files are located in the same dir as Texmod.exe
; DO NOT append the .tpf extension!!
; ONE .tpf file per line!!
TPF_files =
(
NFS UG2 Textures Mod V2.0 By Dragozool
)
WaitBeforeSetAff_secs = 90
CPU_affinity = 2
; Because some important (realtime) Windows kernel functions will run *only*
; on CPU0, do NOT use CPU0.
; Also, since many Intel processors are hyperthreaded, CPU1 actually shares
; the same core as CPU0. In this case, skip CPU1, too.
; So, start using CPU2 and higher.
; ===== PROCESSING =====
; Limit the waiting time for TPF to finish loading
REP_MAX = 10
REP_WAIT = 500
; --- First, kill existing texmod.exe processes
Loop,
{
Process, Exist, %TexMod_exe%
Old_PID = %ErrorLevel%
If Old_PID = 0
Break
Process, Close, %Old_PID%
Sleep, 1000
}
; --- Now we start texmod.exe and wait until its window appear
Run, %TexMod_Dir%\%TexMod_exe%, %TexMod_Dir%, , TexModPID
WinWait, ahk_pid %TexModPID%
WinActivate, ahk_pid %TexModPID%
; --- Choose NFSU2's exe
ControlClick, Button2, ahk_pid %TexModPID%
WinWaitActive, Select Executable
SendInput !n%NFSU_Dir%\%Speed_exe%{Enter}
WinWaitClose, Select Executable
WinActivate, ahk_pid %TexModPID%
; --- Load the TPF files
Loop, parse, TPF_files, `n
{
TPF_file := A_LoopField
ControlClick, Button12, ahk_pid %TexModPID%
SendInput {Down}{Enter}
WinWaitActive, Select Texmod Packages
; The {space}{Backspace} is necessary because for unknown reasons, without this
; combo the first letter of %TexMod_Dir% gets chopped off
SendInput !n {Backspace}%TexMod_Dir%\%TPF_file%.tpf{Enter}
WinWaitClose, Select Texmod Packages
; --- Wait while TPF file is being parsed
rep := 0
Loop,
{
Sleep, %REP_WAIT%
ControlGet, List, List, Col1, SysListView321, ahk_pid %TexModPID%
IfInString, List, %TPF_file%
Break
rep := rep + 1
If (rep > REP_MAX) {
MsgBox, 16, , Waiting too long for %TPF_file%.tpf to be parsed!`n`nScript will now abort!
ExitApp
}
}
Sleep, 1000
}
; --- Start the game, wait for texture loads, and set affinity
ControlClick, Button11, ahk_pid %TexModPID%
Sleep % WaitBeforeSetAff_secs * 1000
Process, Exist, %Speed_exe%
Speed_PID = %ErrorLevel%
; Affinity mask is actually 2^n for CPUn
CPU_aff_mask := 2 ** CPU_affinity
Affinity_Set(CPU_aff_mask, Speed_PID)
; ---Done.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment