If I'm inferring correctly, you're saying the physics flag 0x10 issue is that an actor attached to a non-perfectly-upright surface doesn't stay aligned, that they stay upright? What I saw in the AI turning code definitely explains that, because yes, like when using SetThingLook in COG, PYR are functionally thrown out. To "fix" it would require checking that no other AI/actor code sets look vector, and assuming it doesn't, then making new AI turning code from scratch because what's there probably isn't meaningfully adaptable.
For FTIV's FOV, the values are fed through a trigonometric helper function to get sin/cos. More specifically, it disallows a FOV value less than zero, halves the FOV value, and subtracts it from 90, then passes the result in to a sin/cos function. It's pretty fundamental to how it works and not technically a bug, just doesn't do what pretty much anyone wishes it did (allow searching up to a full 360 degrees). To extend functionality would surely be tricky to not break compatibility with existing COGs, and then COGs using the new behavior wouldn't work correctly vanilla (same input can produce wildly different results). Arguably the same compatibility issue with increasing the find limit, but not quite as bad (same basic results with the same input values, just potentially more results).
Interestingly COG's FirstThingInView doesn't do much itself, and mainly reuses AI target finding code; mentioning because when I was looking at AI turning code, I was often scrolling past AI's FTIV code. Just a happy coincidence that the things you asked about were so intertwined in the executable.
QM
Edit: So regarding the UI toggles, what are you looking for? Being able to read them, or read and write, and to some extent, why?
Just brainstorming a little, if I were to hook up more player settings UI stuff to an existing COG verb, it'd probably be the Automatic X Weapon flags because the SetAutoPickup verb is faulty anyway (so would have near zero chance of someone having relied on it historically, more info in a sec), and since the GetAutoX/SetAutoX verbs are related to user settings already.
So I recall, a long time ago, there being some discussions about using the unused Automatic X Weapon setting bits to propagate in-level settings between levels. I don't recall if anyone ever released anything that did so, but I think I recall the JKArena stuff considering the technique. So backwards compatibility concerns come into play.
Since SetAutoPickup and SetAutoReload set the wrong settings (while SetAutoSwitch works), and SetAutoReload has to be used to set the Auto Pickup flags (so it might have been used), SetAutoPickup modifies the Auto Switch flags which is already accounted for by the functional SetAutoSwitch verb... sooo... the least likely verb to have been used is SetAutoPickup.
So what I'd probably do is modify SetAutoPickup so that if the high bit is set (0x80000000), then instead use the low two bits (0x1,0x2) to set the Auto Reload flags (it's not super likely that someone ever used SetAutoPickup(0x80000003) or similar) and then use other bits there for other UI settings, and retrieved via GetAutoReload, which would return the high bit set to indicate patched behavior is active.
So, an example of compatibility-minded COG would be:
Code:
if(GetAutoReload() & 0x80000000) # check for patched behavior
{
SetAutoPickup(GetAutoReload() ^ 0x40000000); # toggle auto run
}
Also whoa my COG is rusty. I think that'd be correct.
Since vanilla COG can't touch Auto Reload bits, GetAutoReload vanilla should never return values other than 0-3. Any bits used to mess with other settings wouldn't actually be set / cleared in the Auto Reload bits. The high bit would be used to signal that patched behavior is occurring, and SetAutoPickup, even if just being used to set the two real Auto Reload bits, would still need a GetAutoReload() & 0x80000000 test first to make sure you're not clobbering the Auto Switch bits if run by unpatched JK.
Also note that the SetAutoX verbs suck and overwrite their respective settings, and need the COG author to manually or in existing flags. e.g. To change 0x2 to 0x3 requires: SetAutoSwitch(GetAutoSwitch() | 0x1);
Edit 2: Looking at the COG extension verbs, I see:
jkgetwindowgui
jkgetverbosity
jkgetsubtitles
jkgetsfxvolume
jkgetscreensize
jkgetrotatemap
jkgetdisablepageflip
jkgetnohud
jkgetmodpath
jkgetmintexsize
jkgetgammalevel
jkgetframerate
jkgetdrawstatus
jkgetdispstats
jkgetdisplayconfig
jkgetdisablecutscene
jkgetdevmode
jkgetdebugoutput
jkgetcrosshair
jkgetbackbufferinsysmem
jkget3daccel
So at least for reading the settings, everything except auto run might be available?
Edit 3: Okay, analyzed the singleplayer save/load code enough to be positive SubModeFlags IS saved and loaded, so that'll make usage for toggling keyboard turning behavior easy. It also means it doesn't make sense to use them for user settings. To clarify, I don't consider framerate compensated keyboard turning a user choice; it's on because vanilla behavior is faulty, and this toggle will be for obscure compatibility reasons (e.g. detecting keyboard vs mouse turning).
Edit 4: I've been looking at the keyboard turn speed code in depth; ignore the previous post where I suggest a hex edit.
The logic is probably as follows:
- read raw mouse X axis
- multiply by time since last frame
- value will be 0.0 if no mouse input
- read non-raw mouse X axis and keyboard X axis
- multiply by the player's maxrotthrust (usually 180.0)
- multiply by the current move_multiplier, capped at 1.0 (1.0, 0.5 or 0.25)
- if framerate compensated, multiply by (time since last frame / 50.0)
- add the above two together
Things that affect the move_multiplier are crouching, the "slow" (walk) hotkey with auto run off, and standing on water/deepwater surfaces. Also physics flag 0x200000 but according to the DataMaster that flag gets cleared when attached to a surface (haven't verified).
Of note there's a GetThingRotationalThrustMax COG extension verb, but if you're making a level-specific COG, you'd have control over the player's maxrotthrust anyway (via the walkplayer template).
I've not checked the player's rotational velocity via COG yet, but via the debugger, it looks like I'm generally getting 180, 0 or -180; to get 90/-90 did you meet one of the conditions listed above for a 0.5 move_multiplier?
Also note that disabling framerate compensated keyboard turning will also affect mouse turning (but currently not pitch with either nor the center view hotkey).
Edit 5: My apologies for how unwieldy this post has become. There are quite a few questions in there for you SMLiberator; I imagine it'll be a pain to tackle them all.
Also, bad news regarding that input delay fix; what seems to fix it for you, murders framerate on held keypresses on Windows, so the change won't be part of any future releases. It's actually faulty code that puts a sleep between each keypress message (the type that goes to the window's message pump, and that starts spamming after the keypress repeat timeout lapses). Here's an IPS file to streamline applying the patch in the future:
https://drive.google.com/file/d/1Arv...0gH_7IFck/view
IPS is a mediocre format, but for such a small patch and considering the availability of tools to apply IPS patches, seems adequate.
Does vanilla JK have input delay for you? Because given what you've mentioned about JK13, 2018 and 2022, I would expect it to.
I'll have a test version where SetSubModeFlags(0x80000000); will disable all framerate compensation for input soon (see next edit). It'll also include a raised transparent surface limit (from vanilla 32 raised to 512).
Edit 6: And here's a test version:
https://drive.google.com/file/d/16iK...JS6baXahK/view
This needs to be applied to a JK 2022 executable, not vanilla. It doesn't include the linuxinputsleep patch from edit 5, so apply that as well (or don't, whatever).
The increased transparent surface limit will be obvious as long as you have a test case to check. I'm fairly certain the test level I have you made for me.
For the framerate compensated input flag, you'll need to rig up a COG to call SetSubModeFlags(0x80000000);. Let's pretend it's to control a drivable vehicle; I'd suggest putting SetSubModeFlags in the part where the player enters the vehicle, and ClearSubModeFlags when they exit, and then PrintVector(GetThingRotVel(player)); while driving? While the flag is set, try a save and load to make sure the flag persists through a load.
Let me know if IPS is no good, but there should be multiple IPS patchers available per platform, plus even browser based options.