Skip to content
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
37 changes: 23 additions & 14 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ function cliScaleOverride(name: string, idx: number): void {
}
cliScaleOverride('--render-scale', SET.SET_RENDER_SCALE);
cliScaleOverride('--output-scale', SET.SET_OUTPUT_SCALE);
// `--pt off|prog|rt` overrides the persisted path-tracing mode for this
// launch. Applied with the rest of the graphics settings below (and
// inert on devices without ray query, same as the menu row).
const cliPt = cliArg('--pt');
if (cliPt === 'off' || cliPt === '0') SET.set(SET.SET_PT, 0);
else if (cliPt === 'prog' || cliPt === '1') SET.set(SET.SET_PT, 1);
else if (cliPt === 'rt' || cliPt === '2') SET.set(SET.SET_PT, 2);

FEEL.setShakeScale(SET.get(SET.SET_SHAKE));
initMenus();
Expand Down Expand Up @@ -1663,15 +1670,10 @@ let dbgSsao = true;
// Progressive accumulates while the camera is still (stand still and the
// image converges); realtime is the denoised gameplay mode. No-op on
// devices without hardware ray query.
let dbgPtMode = 0;
// PT state lives in the settings array (SET_PT) — the menu row, the F9
// debug cycle, the --pt CLI flag and the HUD all read/write one value.
// applyGraphicsSettings() pushed the persisted mode at boot.
const ptSupported = isPathTracingSupported();
// `--pt prog|rt` (or 1|2) starts the run already in that mode. Goes through
// dbgPtMode so the F9 cycle and the HUD tag stay truthful.
const ptArg = cliArg('--pt');
if (ptSupported) {
if (ptArg === 'prog' || ptArg === '1') { dbgPtMode = 1; setPathTracing(1); }
else if (ptArg === 'rt' || ptArg === '2') { dbgPtMode = 2; setPathTracing(2); }
}
let dbgSsr = true;
let dbgShadow = true;
disableCursor();
Expand Down Expand Up @@ -1786,10 +1788,10 @@ const PERFTEST = false;
// player alive, and logs fps / worst-frame / alive-enemy count per 60-frame
// window; the profiler turns on for the final third to get a combat per-pass
// table.
const PERF_MODE = 0;
const PERF_MODE = 1;
// false = stay on the title screen (stationary world backdrop — used for
// external flicker captures); true = auto-start the run at frame 20.
const PERF_START_GAME = false;
const PERF_START_GAME = true;
const PERF_SETTLE = 30; // frames to let a config change settle
const PERF_MEASURE = 120; // frames per measurement window
const PERF_STAGES = 11;
Expand Down Expand Up @@ -1827,7 +1829,13 @@ function perfKillOne(): void {
enAlive[i] = 0;
enDying[i] = 1;
enDeathT[i] = 0;
enDeathYaw[i] = 0;
enDeathYaw[i] = enHeading[i];
// SH-031 ragdoll fields — the death anim reads these into native
// f64 params, so a scripted kill must set them like a real shot.
enDeathDX[i] = 0;
enDeathDY[i] = 0.3;
enDeathDZ[i] = -1;
enDeathImp[i] = 40;
setBodyPosition(enBody[i], vec3(enX[i], -100, enZ[i]), false);
playSound(sfxAttack);
console.log('PERFKILL t=' + getTime().toFixed(2)
Expand Down Expand Up @@ -1969,8 +1977,9 @@ while (!windowShouldClose() && !aitestDone) {
if (isKeyPressed(Key.F7)) { dbgSsr = !dbgSsr; setSsrEnabled(dbgSsr); }
if (isKeyPressed(Key.F8)) { dbgShadow = !dbgShadow; setShadowsEnabled(dbgShadow); }
if (isKeyPressed(Key.F9) && ptSupported) {
dbgPtMode = (dbgPtMode + 1) % 3;
setPathTracing(dbgPtMode);
const ptNext = (SET.get(SET.SET_PT) + 1) % 3;
SET.set(SET.SET_PT, ptNext);
setPathTracing(ptNext);
}

const input = readInput(dtReal);
Expand Down Expand Up @@ -3798,7 +3807,7 @@ while (!windowShouldClose() && !aitestDone) {
+ ' F8 SHADOW ' + (dbgShadow ? 'ON ' : 'off')
// The vN suffix is a build tag: bump it with each PT engine drop
// so a stale main.exe is identifiable at a glance in the HUD.
+ ' F9 PT ' + (!ptSupported ? 'n/a' : (dbgPtMode === 0 ? 'off' : (dbgPtMode === 1 ? 'PROG' : 'RT'))) + ' v10';
+ ' F9 PT ' + (!ptSupported ? 'n/a' : (SET.get(SET.SET_PT) === 0 ? 'off' : (SET.get(SET.SET_PT) === 1 ? 'PROG' : 'RT'))) + ' v11';
drawRect(6, 6, 760, 30, { r: 0, g: 0, b: 0, a: 170 });
drawText(dbgLine, 14, 12, 18, { r: 255, g: 240, b: 120, a: 255 });
}
Expand Down
41 changes: 40 additions & 1 deletion src/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import {
setOutputScale, setRenderScale, setShadowsEnabled,
setSsaoEnabled, setSsrEnabled, setSsgiEnabled, setBloomEnabled,
setPathTracing, isPathTracingSupported,
} from 'bloom/core';
import * as SET from './settings';
import * as MIX from './audio-mix';
Expand All @@ -34,6 +35,8 @@ export const MENU_LEVELS = 3;
const ROW_ACTION = 0;
const ROW_SLIDER = 1;
const ROW_TOGGLE = 2;
// Three named states (the path-tracing row: OFF / QUALITY / REALTIME).
const ROW_TRI = 3;

// 0 current menu 1 selected row 2 stick-repeat cooldown
const S = [MENU_NONE, 0, 0];
Expand Down Expand Up @@ -65,6 +68,7 @@ const PAUSE_COUNT = 5;
const SET_LABELS: string[] = [
'DISPLAY RESOLUTION', 'RENDER RESOLUTION',
'SHADOWS', 'AMBIENT OCCLUSION', 'REFLECTIONS', 'GLOBAL ILLUMINATION', 'BLOOM',
'PATH TRACING',
'MASTER VOLUME', 'MUSIC VOLUME', 'SFX VOLUME',
'LOOK SENSITIVITY', 'PAD SENSITIVITY', 'INVERT Y',
'FIELD OF VIEW', 'CAMERA SHAKE',
Expand All @@ -75,6 +79,7 @@ const SET_LABELS: string[] = [
const SET_KINDS: number[] = [
ROW_SLIDER, ROW_SLIDER,
ROW_TOGGLE, ROW_TOGGLE, ROW_TOGGLE, ROW_TOGGLE, ROW_TOGGLE,
ROW_TRI,
ROW_SLIDER, ROW_SLIDER, ROW_SLIDER,
ROW_SLIDER, ROW_SLIDER, ROW_TOGGLE,
ROW_SLIDER, ROW_SLIDER,
Expand All @@ -85,6 +90,7 @@ const SET_KINDS: number[] = [
const SET_IDX: number[] = [
SET.SET_OUTPUT_SCALE, SET.SET_RENDER_SCALE,
SET.SET_SHADOWS, SET.SET_SSAO, SET.SET_SSR, SET.SET_SSGI, SET.SET_BLOOM,
SET.SET_PT,
SET.SET_MASTER_VOL, SET.SET_MUSIC_VOL, SET.SET_SFX_VOL,
SET.SET_SENS, SET.SET_PAD_SENS, SET.SET_INVERT_Y,
SET.SET_FOV, SET.SET_SHAKE,
Expand All @@ -98,6 +104,7 @@ const SET_IDX: number[] = [
const SET_MIN: number[] = [
0.5, 0.5,
0, 0, 0, 0, 0,
0,
0, 0, 0,
0.2, 0.2, 0,
60, 0,
Expand All @@ -106,6 +113,7 @@ const SET_MIN: number[] = [
const SET_MAX: number[] = [
1.0, 1.0,
1, 1, 1, 1, 1,
2,
1, 1, 1,
3.0, 3.0, 1,
100, 1,
Expand All @@ -114,12 +122,13 @@ const SET_MAX: number[] = [
const SET_STEP: number[] = [
0.05, 0.05,
1, 1, 1, 1, 1,
1,
0.05, 0.05, 0.05,
0.1, 0.1, 1,
5, 0.1,
1, 1,
1, 1, 0];
const SET_COUNT_ROWS = 20;
const SET_COUNT_ROWS = 21;

export function initMenus(): void {
S[0] = MENU_NONE; S[1] = 0; S[2] = 0;
Expand Down Expand Up @@ -150,6 +159,10 @@ function adjust(dir: number): void {
let v = SET.get(idx);
if (kind === ROW_TOGGLE) {
v = v !== 0 ? 0 : 1;
} else if (kind === ROW_TRI) {
v = v + dir;
if (v < SET_MIN[r]) v = SET_MIN[r];
if (v > SET_MAX[r]) v = SET_MAX[r];
} else {
v = v + dir * SET_STEP[r];
if (v < SET_MIN[r]) v = SET_MIN[r];
Expand Down Expand Up @@ -183,6 +196,10 @@ function applyLive(idx: number): void {
setSsgiEnabled(SET.get(SET.SET_SSGI) !== 0);
} else if (idx === SET.SET_BLOOM) {
setBloomEnabled(SET.get(SET.SET_BLOOM) !== 0);
} else if (idx === SET.SET_PT) {
// No-op on devices without hardware ray query — the row reads N/A
// there and the value is inert (fallback matrix, PT-5).
if (isPathTracingSupported()) setPathTracing(SET.get(SET.SET_PT));
}
}

Expand All @@ -197,6 +214,7 @@ export function applyGraphicsSettings(): void {
setSsrEnabled(SET.get(SET.SET_SSR) !== 0);
setSsgiEnabled(SET.get(SET.SET_SSGI) !== 0);
setBloomEnabled(SET.get(SET.SET_BLOOM) !== 0);
if (isPathTracingSupported()) setPathTracing(SET.get(SET.SET_PT));
}

function confirm(): void {
Expand Down Expand Up @@ -227,6 +245,13 @@ function confirm(): void {
S[1] = 0;
} else if (SET_KINDS[S[1]] === ROW_TOGGLE) {
adjust(1);
} else if (SET_KINDS[S[1]] === ROW_TRI) {
// Confirm/click cycles through the three states (wrapping);
// left/right arrows still step and clamp like a slider.
const idx = SET_IDX[S[1]];
SET.set(idx, (SET.get(idx) + 1) % 3);
applyLive(idx);
MIX.uiMove();
}
}
}
Expand Down Expand Up @@ -393,6 +418,20 @@ export function drawMenu(sw: number, sh: number): void {
const on = v !== 0;
drawText(on ? 'ON' : 'OFF', barX, ry + 8, 24,
on ? { r: 150, g: 235, b: 150, a: 255 } : { r: 150, g: 150, b: 155, a: 200 });
} else if (kind === ROW_TRI) {
// Path tracing. QUALITY = progressive (converges standing still,
// for screenshots); REALTIME = denoised gameplay mode. On a GPU
// without ray query the row is inert and says why.
if (!isPathTracingSupported()) {
drawText('N/A (NO RAY TRACING)', barX, ry + 8, 20,
{ r: 140, g: 140, b: 145, a: 180 });
} else if (v === 0) {
drawText('OFF', barX, ry + 8, 24, { r: 150, g: 150, b: 155, a: 200 });
} else if (v === 1) {
drawText('QUALITY (STILLS)', barX, ry + 8, 24, { r: 235, g: 210, b: 140, a: 255 });
} else {
drawText('REALTIME', barX, ry + 8, 24, { r: 150, g: 235, b: 150, a: 255 });
}
} else {
const t = (v - SET_MIN[i]) / (SET_MAX[i] - SET_MIN[i]);
drawRect(barX, ry + 16, barW, 8, { r: 70, g: 70, b: 76, a: 220 });
Expand Down
14 changes: 12 additions & 2 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ export const SET_SSAO = 15; // 0/1 — ambient occlusion
export const SET_SSR = 16; // 0/1 — screen-space reflections
export const SET_SSGI = 17; // 0/1 — global illumination
export const SET_BLOOM = 18; // 0/1
export const SET_COUNT = 19;
// PT-5 — hardware path tracing: 0 off, 1 progressive (converges while
// the camera is still — stills/photo mode), 2 realtime (SVGF-denoised
// gameplay mode). Applied only when the device reports ray-query
// support; on anything else the setting is inert and the menu says so.
export const SET_PT = 19;
export const SET_COUNT = 20;

const V = new Array<number>(SET_COUNT);

Expand Down Expand Up @@ -81,6 +86,9 @@ function defaults(): void {
V[SET_SSR] = 1;
V[SET_SSGI] = 1;
V[SET_BLOOM] = 1;
// Off by default: Lumen is the default GI everywhere; path tracing is
// opt-in (it trades ~half the frame rate for traced lighting).
V[SET_PT] = 0;
for (let i = 0; i < MAX_ARENAS; i++) best[i] = 0;
M[0] = 0;
}
Expand Down Expand Up @@ -171,6 +179,7 @@ export function loadSettings(): void {
V[SET_SSR] = num(vd, 'ssr', V[SET_SSR]);
V[SET_SSGI] = num(vd, 'ssgi', V[SET_SSGI]);
V[SET_BLOOM] = num(vd, 'bloom', V[SET_BLOOM]);
V[SET_PT] = num(vd, 'pathTracing', V[SET_PT]);

const ac: any = o['access'];
V[SET_SHAKE] = num(ac, 'shake', V[SET_SHAKE]);
Expand Down Expand Up @@ -203,7 +212,8 @@ export function saveSettings(): void {
+ ', "ssao": ' + V[SET_SSAO]
+ ', "ssr": ' + V[SET_SSR]
+ ', "ssgi": ' + V[SET_SSGI]
+ ', "bloom": ' + V[SET_BLOOM] + ' },\n';
+ ', "bloom": ' + V[SET_BLOOM]
+ ', "pathTracing": ' + V[SET_PT] + ' },\n';
s = s + ' "access": { "shake": ' + V[SET_SHAKE]
+ ', "colorblind": ' + V[SET_COLORBLIND]
+ ', "captions": ' + V[SET_CAPTIONS] + ' },\n';
Expand Down