Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add horizontal FOV converter #132

Merged
merged 1 commit into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion layout/pages/settings/video.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

<scripts>
<include src="file://{scripts}/pages/settings/page.js" />
<include src="file://{scripts}/util/math.js" />
<include src="file://{scripts}/pages/settings/fov.js" />
</scripts>

<Panel class="settings-page">
Expand All @@ -31,7 +33,21 @@
<Label class="settings-group__title" text="#Settings_Video" />
</Panel>

<SettingsSlider text="#Settings_Video_FOV" min="50" max="130" convar="fov_desired" hasdocspage="false" />
<SettingsSlider id="FOV" text="#Settings_Video_FOV" min="50" max="130" convar="fov_desired" hasdocspage="false" onvaluechanged="Fov.updateFOV()" />

<Panel class="settings-group__combo" onload="Fov.loadSettings()" infotitle="#Settings_Video_Horizontal_FOV" infomessage="#Settings_Video_Horizontal_FOV_Info">
<Panel class="settings-enum">
<Label text="#Settings_Video_Horizontal_FOV" class="settings-enum__title" />
<Panel class="settings-enum__values">
<TextEntry id="FOV_Horizontal" class="textentry settings-slider__textentry HasInput ml-4" multiline="false" textmode="numeric" oninputsubmit="Fov.updateHorizontalFov()" />
<DropDown id="FOV_Horizontal_AspectRatioEnum" class="dropdown ml-4" menuclass="dropdown-menu" onuserinputsubmit="Fov.updateFOV()">
<Label text="#Settings_Video_AspectRatio_Normal" value="0" id="aspectratio0" />
<Label text="#Settings_Video_AspectRatio_16x9" value="1" id="aspectratio1" />
<Label text="#Settings_Video_AspectRatio_16x10" value="2" id="aspectratio2" />
</DropDown>
</Panel>
</Panel>
</Panel>

<SettingsSlider text="#Settings_Video_MaxFPS" min="0" max="400" convar="fps_max" infomessage="#Settings_Video_MaxFPS_Info" hasdocspage="false" />

Expand Down
62 changes: 62 additions & 0 deletions scripts/pages/settings/fov.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
class Fov {
static panels = {
/** @type {SettingsSlider} @static */
fov: $('#FOV'),
/** @type {TextEntry} @static */
horizontalFov: $('#FOV_Horizontal'),
aspectRatio: $('#FOV_Horizontal_AspectRatioEnum')
};

static loadSettings() {
this.panels.aspectRatio.SetSelected('aspectratio1');
this.updateFOV();
}

static aspectRatio() {
const id = this.panels.aspectRatio.GetSelected().id;
switch (id) {
case 'aspectratio0':
return 4 / 3;
case 'aspectratio1':
return 16 / 9;
case 'aspectratio2':
return 16 / 10;
}
return Number.NaN;
}

// based on https://casualhacks.net/Source-FOV-calculator.html
wertiop121 marked this conversation as resolved.
Show resolved Hide resolved
static fovToHorizontal(fov) {
const ratioRatio = this.aspectRatio() / (4 / 3);
return 2 * rad2deg(Math.atan(Math.tan(deg2rad(fov) / 2) * ratioRatio));
}

static horizontalToFov(horizontalFov) {
const ratioRatio = this.aspectRatio() / (4 / 3);
return 2 * rad2deg(Math.atan(Math.tan(deg2rad(horizontalFov) / 2) / ratioRatio));
}

static updateFOV() {
if (!this.panels.fov || !this.panels.horizontalFov) return;

let fov = GameInterfaceAPI.GetSettingFloat('fov_desired');
fov = Math.round(this.fovToHorizontal(fov));

if (!Number.isNaN(fov)) {
this.panels.horizontalFov.text = fov;
}
}

static updateHorizontalFov() {
if (!this.panels.fov || !this.panels.horizontalFov) return;

let fov = Number.parseFloat(this.panels.horizontalFov.text);
fov = Math.round(this.horizontalToFov(fov));
PeenScreeker marked this conversation as resolved.
Show resolved Hide resolved

if (!Number.isNaN(fov)) {
const fovText = this.panels.fov.FindChildTraverse('Value');
fovText.text = fov;
fovText.Submit();
}
}
}
18 changes: 8 additions & 10 deletions scripts/pages/settings/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,7 @@ class MainMenuSettings {

static initPanelsRecursive(panel) {
// Initialise info panel event handlers
if (this.isSettingsPanel(panel) || this.isSpeedometerPanel(panel)) {
this.setPanelInfoEvents(panel);
}
this.setPanelInfoEvents(panel);

// Initialise all the settings using persistent storage
// Only Enum and EnumDropDown are currently supported, others can be added when/if needed
Expand Down Expand Up @@ -312,15 +310,19 @@ class MainMenuSettings {

static setPanelInfoEvents(panel) {
const message = panel.GetAttributeString('infomessage', '');
const title = panel.GetAttributeString('infotitle', '');

// Don't set events if there's no info to show
if (!this.isSettingsPanel(panel) && message === '' && title === '' && !panel.convar && !panel.bind) return;

// Default to true if not set
const hasDocs = !(panel.GetAttributeString('hasdocspage', '') === 'false');

panel.SetPanelEvent('onmouseover', () => {
// Set onmouseover events for all settings panels
this.showInfo(
// If a panel has a specific title use that, if not use the panel's name. Child ID names vary between panel types, blame Valve
panel.GetAttributeString('infotitle', '') ||
panel.FindChildTraverse('Title')?.text ||
panel.FindChildTraverse('title')?.text,
title || panel.FindChildTraverse('Title')?.text || panel.FindChildTraverse('title')?.text,
message,
panel.convar ?? panel.bind,
hasDocs,
Expand Down Expand Up @@ -434,8 +436,4 @@ class MainMenuSettings {
'ConVarColorDisplay'
].includes(panel.paneltype);
}

static isSpeedometerPanel(panel) {
return ['SpeedometersContainer', 'RangeColorProfilesContainer'].includes(panel.id);
}
}
8 changes: 8 additions & 0 deletions scripts/util/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,11 @@ function mapAngleToScreenDist(angle: number, fov: number, length: number, scale:
return Math.round((1 + Math.tan(angle * 0.5) / Math.tan(fov * 0.5)) * screenDist * 0.5);
}
}

function deg2rad(x: number): number {
return (x / 180) * Math.PI;
}

function rad2deg(x: number): number {
return (x * 180) / Math.PI;
}
Loading