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
8 changes: 7 additions & 1 deletion core/materialsystem1/DefaultShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,13 @@ BEGIN_SHADER_CLASS(
bool SetupRenderPass(IShaderAPI* renderAPI, const PipelineInputParams& pipelineParams, ArrayCRef<RenderBufferInfo> uniformBuffers, const RenderPassContext& passContext, IMaterial* originalMaterial) override
{
const MatSysDefaultRenderPass* rendPassInfo = static_cast<const MatSysDefaultRenderPass*>(passContext.data);
ASSERT_MSG(rendPassInfo, "Must specify MatSysDefaultRenderPass in userData when drawing with default material");
if (!rendPassInfo)
{
ASSERT_FAIL("No render pass data specified");
return false;
}

ASSERT_MSG(rendPassInfo->type == RENDERPASS_DEFAULT, "Must specify MatSysDefaultRenderPass in userData when drawing with default material");
const uint pipelineId = GenDefaultPipelineId(passContext.recorder->GetRenderTargetFormats(), passContext.recorder->GetDepthTargetFormat(), *rendPassInfo, pipelineParams.primitiveTopology);

auto it = m_renderPipelines.find(pipelineId);
Expand Down
8 changes: 4 additions & 4 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Related documents:
| [codestyle.md](codestyle.md) | Code style for new files |
| [framework_ds.md](framework_ds.md) | Containers, strings, smart pointers (`framework/ds`) |
| [framework_math.md](framework_math.md) | Math library (`framework/math`) |
| [framework_core.md](framework_core.md) | Console variables/commands, command line, profiler |
| [framework_core.md](framework_core.md) | Console variables/commands, command line, console tool helpers (`cmdlib.h`), profiler |
| [framework_platform.md](framework_platform.md) | Message boxes, timers |
| [framework_multithreading.md](framework_multithreading.md) | Threads, locks, signals, TLS, atomics |
| [framework_job_manager.md](framework_job_manager.md) | Job manager and `g_parallelJobs` |
Expand Down Expand Up @@ -87,12 +87,12 @@ Public interfaces are declared in `public/` and implemented in `core/` or `share
| `shared/audio/` | Audio system on OpenAL, sound emitters/scripts/mixer; `source/` holds WAV/OGG sources |
| `shared/physics/` | EqPhysics engine on top of Bullet collision — see [physics_overview.md](physics_overview.md) |
| `shared/equi/` | EqUI interface library: manager, controls, scheme |
| `shared/imgui_backend/` | ImGui host and material-system renderer backend |
| `shared/imgui_backend/` | ImGui host (`g_imGuiHost`), SDL platform backend and material-system renderer backend |
| `shared/scripting/` | ESL — Lua binding library |
| `shared/movie/` | WebM movie player: AV1 video (dav1d), Vorbis audio, YUV to RGBA conversion on GPU (`MovieYUV` shader) |
| `shared/network/` | UDP networking |
| `shared/input/` | Input command binder |
| `shared/sys/` | Application host: main loop, window, states, console, joystick, config loader; `sys/scripting/` exposes engine subsystems to ESL, `sys/imgui/` is the ImGui platform backend |
| `shared/sys/` | Application host: main loop, window, states, console, joystick, config loader; `sys/scripting/` exposes engine subsystems to ESL |
| `shared/components/`, `shared/entity/` | Component system and data tables (no engine project; compiled by consumers) |
| `tools/` | Content tools (see below); `localization_tool/` is a separate C# project, `imp-exp blender/` is a Blender add-on |
| `samples/` | Sample applications, each with its own workspace `premake5.lua` |
Expand Down Expand Up @@ -208,7 +208,7 @@ All are static libraries using `public` and `shared` include paths.
| `studioLib` | `studio/**` | studioFileLib |
| `animatingLib` | `animating/**` | studioLib |
| `equiLib` | `equi/**` | fontLib (imgui) |
| `imguiBackendLib` | `imgui_backend/**` | (imgui) |
| `imguiBackendLib` | `imgui_backend/**` | (SDL2, imgui) |
| `networkLib` | `network/**` except `NETThread.cpp` | (zlib) |
| `soundSystemLib` | `audio/**` | (minivorbis, openal-soft, imgui) |
| `physicsLib` | `physics/**` | (bullet2) |
Expand Down
3 changes: 3 additions & 0 deletions docs/codestyle.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ The reference shows the general layout; where it disagrees with this document, t
4. the file's own header last.
- Public interfaces live under `public/` (`I`-prefixed abstract classes); implementations live next
to their module (`C`-prefixed classes).
- In `.cpp` files, console variable and command declarations (`DECLARE_CVAR*`, `DECLARE_CMD*`,
see `framework_core.md`) go at the top, after the includes and before function code: file-local
helpers and other functions are placed below them.
- Logical sections inside a file are separated with a dashed comment line:

```cpp
Expand Down
21 changes: 20 additions & 1 deletion docs/framework_core.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# framework/core — console, command line, profiler
# framework/core — console, command line, console tool helpers, profiler

This document covers the console variable/command system, the command line and the profiling
interface. Headers live in `framework/core/` (`coreLib`) and `public/core/`; implementations of
Expand Down Expand Up @@ -142,6 +142,25 @@ if (idx != -1)
const char* value = g_cmdLine->GetArgumentsOf(g_cmdLine->Find("-game"));
```

## Console tool helpers — `framework/core/cmdlib.h`

Included by `core/core_common.h`.

- `Install_SpewFunction()` — prints log messages to the process console with colors by message type
(and `OutputDebugString` on Windows). Console tools (`egfca`, `animca`, ...) call it first in
`main`.
- `RunProcessToConsole(cmdLine, exitCode)` — runs a command, waits for it and prints its stdout and
stderr line by line with `Msg`. On Windows the process gets no console window
(`CreateProcess` + pipe), so it also works from windowed applications where `_popen` does not;
elsewhere it uses `popen`. Returns `false` if the process could not be started. Child output
that is block-buffered appears when the process flushes or exits.

```cpp
int exitCode = 0;
if (!RunProcessToConsole("egfca.exe models/box.esc", exitCode))
MsgError("Failed to run egfca\n");
```

## Profiler — `framework/core/profiler.h`

Profiling markers are compiled in all configurations except `Retail` (`PROFILE_ENABLE`); in
Expand Down
106 changes: 88 additions & 18 deletions docs/sys_application_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ input routing, configs and screenshots. An application links `sysLib` (premake p
| `sys_window.cpp/.h` | Window creation, SDL init, game loop (`sysHostInit`, `sysHostGameLoop`, `sysHostTerminate`) |
| `sys_host.cpp/.h` | `g_pHost` (`CGameHost`) — systems, frame, video modes, cursor, input events |
| `sys_state.cpp/.h` | `CAppStateBase`, `eqAppStateMng` — app states |
| `sys_in_console.cpp/.h` | `g_consoleInput` (`CEqConsoleInput`) — developer console, log, ImGui frame |
| `sys_viewport.cpp/.h` | `CHostViewport` — state rendering inside an ImGui window |
| `sys_in_console.cpp/.h` | `g_consoleInput` (`CEqConsoleInput`) — developer console, log |
| `sys_in_joystick.cpp/.h` | `CEqGameControllerSDL` — game controllers |
| `cfgloader.cpp/.h` | `WriteCfgFile`, `writecfg` |
| `sys_version.cpp/.h` | `ENGINE_NAME`, `ENGINE_VERSION`, `COMPILE_*`, `GetEngineBuildNumber()` |
| `imgui/imgui_impl_sys.*` | ImGui platform backend for SDL |
| `scripting/` | Engine Lua state and bindings ([scripting_esl_overview.md](scripting_esl_overview.md)) |

`sysLib` also compiles `shared/input` ([input_overview.md](input_overview.md)) and uses
`renderUtilLib`, `equiLib`, `movieLib`, `scriptLib`, SDL2 and the ImGui backend.
`renderUtilLib`, `equiLib`, `movieLib`, `scriptLib`, SDL2 and `imguiBackendLib` (`g_imGuiHost`,
`shared/imgui_backend`, which also contains the ImGui platform backend for SDL).

## Start-up and shutdown

Expand All @@ -39,7 +40,8 @@ WinMain / main
│ │ ├─ window (vid_mode, vid_fullscreen, vid_screen), command line (+cmd value)
│ │ ├─ g_matSystem->Init() RHI on the SDL window
│ │ ├─ g_fontCache, g_localizer (+GAME_VERSION, BUILD_NUMBER tokens),
│ │ │ debugoverlay, equi::Manager, g_inputCommandBinder, g_consoleInput (ImGui)
│ │ │ debugoverlay, g_imGuiHost (ImGui on the SDL window), equi::Manager,
│ │ │ g_inputCommandBinder, g_consoleInput
│ │ └─ REGISTER_INTERNAL_SHADERS() material shaders compiled into the application
│ └─ CEqGameControllerSDL::Init()
├─ sysHostGameLoop()
Expand Down Expand Up @@ -101,6 +103,7 @@ A state is one mode of the application (menu, game, editor). Derive from `CAppSt
| `HandleKeyPress`, `HandleMouseClick`, `HandleMouseMove`, `HandleMouseWheel`, `HandleJoyAxis` | Input not consumed by console / ImGui / EqUI |
| `GetMouseCursorProperties(visible, centered)` | Cursor visibility and relative (centered) mouse mode |
| `GetTimescale()` | Time scale for this state's `dt` |
| `GetViewport()` | `CHostViewport` the state renders to, `nullptr` for the whole window (see [Host viewport](#host-viewport--chostviewport)) |

State management (`eqAppStateMng`):

Expand Down Expand Up @@ -130,15 +133,19 @@ frame the loop sleeps `sys_sleep` ms (default 1).
1. Measures time. With `sys_maxfps` set, the frame is skipped until enough time passed; the frame
time is clamped to 0.001–0.1 s.
2. `g_onBeginFrame`, controller button repeats, cursor state.
3. `BeginScene`: `g_matSystem->BeginFrame`, `r_wireframe` / `r_overdraw`, console / ImGui frame
start.
3. `BeginScene`: `g_matSystem->BeginFrame`, console frame start, ImGui frame start
(`g_imGuiHost->BeginFrame`, debug menus while the console is open), `r_wireframe` /
`r_overdraw`.
4. `eqAppStateMng::UpdateStates(dt × state timescale × sys_timescale)` — the current state
renders and queues its command buffers.
5. EqUI render, full-screen edge AA, `g_matSystem->SubmitQueuedCommandsAwaitable()`.
6. Debug overlay with engine statistics (FPS, draw / dispatch counts, GPU and system memory),
`r_showFPS`, `r_showFPSGraph`, input debug drawing.
7. `EndScene`: screenshot (without console / ImGui), console and ImGui drawing,
`g_matSystem->EndFrame()`.
`r_showFPS`, `r_showFPSGraph`. Screenshot (without console / ImGui), then one render pass with
the debug overlay, input debug drawing, console (`g_consoleInput->EndFrame`) and ImGui
(`g_imGuiHost->EndFrame`). With a visible state viewport, EqUI, debug overlays, input debug
drawing and the console go to the viewport target, ImGui is drawn in a separate backbuffer pass
and the screenshot is taken after it (see [Host viewport](#host-viewport--chostviewport)).
7. `EndScene`: `g_matSystem->EndFrame()`.
8. Pending fullscreen toggle, `g_onEndFrame`.

`GetFrameTime()` returns the current frame time; `GetWindowSize()`, `GetDefaultFont()`,
Expand All @@ -165,29 +172,92 @@ dispatched by `CGameHost`:

| Event | Order |
|---|---|
| Keyboard | console → EqUI → state `HandleKeyPress` |
| Mouse buttons | console / ImGui → EqUI → (touch emulation with `m_clicks_to_touch`) → state `HandleMouseClick` |
| Keyboard | console toggle key → ImGui → console → EqUI → state `HandleKeyPress` |
| Mouse buttons | ImGui → console → EqUI → (touch emulation with `m_clicks_to_touch`) → state `HandleMouseClick` |
| Mouse movement | console / ImGui position → EqUI → `g_inputCommandBinder->OnVectorEvent(MOU_MOVE)` → state `HandleMouseMove` |
| Mouse wheel | console → binder (`MOU_MOVE`) → state `HandleMouseWheel` |
| Mouse wheel | ImGui → console → binder (`MOU_MOVE`) → state `HandleMouseWheel` |
| Controller buttons / axes | binder → state `HandleKeyPress` / `HandleJoyAxis` |
| Touch | binder touch zones |
| Text input | console |
| Text input | ImGui → console |

With a visible state viewport (`GetViewport()`), the console, EqUI and the state receive mouse
buttons, movement and wheel only over the viewport, in viewport coordinates. Keys and text go past
the ImGui check while the viewport window is focused or the console is open, unless an ImGui text
field is active. See [Host viewport](#host-viewport--chostviewport).

Keyboard keys and mouse buttons reach command bindings only if the state forwards them to
`g_inputCommandBinder->OnPressEvent` (see [input_overview.md](input_overview.md)). Input is ignored
for 0.25 s after the window regains focus.

ImGui (`g_imGuiHost->Input*`) receives keys, mouse buttons, wheel and text first. While an ImGui
item is hovered, active or focused, or ImGui wants the mouse / keyboard
(`g_imGuiHost->IsImGuiItemsInFocus()`), the event goes no further; key releases still reach the
console so its modifier state does not stick.

## Host viewport — `CHostViewport`

A state can render into a render target shown in an ImGui window instead of the whole window
(tools with panels around the scene). The state owns a `CHostViewport` and returns it from
`CAppStateBase::GetViewport()`.

```cpp
CHostViewport m_viewport{ "egfman2_scene" };

CHostViewport* GetViewport() override { return &m_viewport; }

// ImGui handler (runs in BeginScene, before Update)
if (ImGui::Begin("Scene"))
m_viewport.DrawImGui(); // fills the available content region
ImGui::End();

// Update
const IVector2D viewSize = m_viewport.GetSize();
projMat = perspectiveMatrixY(fov, viewSize.x, viewSize.y, zNear, zFar);
g_renderAPI->BeginRenderPass(
Builder<RenderPassDesc>()
.ColorTarget(m_viewport.GetColorTarget(), true, clearColor)
.DepthStencilTarget(m_viewport.GetDepthTarget())
.DepthClear()
.End());
```

- `DrawImGui(size)` resizes the color and depth targets (backbuffer formats, `ResizeRenderTarget`)
to the drawn size and puts an invisible button with the image in the current ImGui window. The
viewport is *visible* only in a frame where `DrawImGui` was called.
- Viewports are disabled in `Retail` and `Profile` builds (`HOST_VIEWPORT_ENABLED` in
`sys_viewport.h`): `DrawImGui` does nothing and the viewport is never visible.
- When the viewport is not visible (ImGui window closed, `Retail` or `Profile` build),
`GetColorTarget`, `GetDepthTarget` and `GetSize` return the backbuffer, the default depth buffer
and the window size, and the host routes input as without a viewport.
- Input: mouse coordinates passed to the state handlers are relative to the viewport. A button
pressed over the viewport captures the mouse until all captured buttons are released, so drags
continue outside the viewport. Mouse movement and wheel reach the state while the mouse is over
the viewport or captured. Key releases always reach the state, so keys do not stick when focus
moves away.
- `CGameHost::SetCursorPosition` takes viewport coordinates, and a centered cursor
(`GetMouseCursorProperties`) is warped to the viewport center.
- `GetScreenRect`, `ToViewport`, `ToWindow` convert between window and viewport coordinates.
- The state viewport is the main viewport: the host draws EqUI (`equi::Manager->Render(target)`,
view frame of the viewport size), debug overlays (`debugoverlay->Draw` with the viewport targets),
`r_showFPS`, input debug drawing and the console only into it. ImGui stays in the window
backbuffer. Full-screen edge AA is skipped: its luma pass needs a storage source texture.
- `screenshot` with a visible viewport saves the whole window with ImGui, since the viewport gets
to the backbuffer only through ImGui.

## Developer console — `g_consoleInput`

- Opened by the `+con_toggle` command (bind it to a key, e.g. `bind GRAVE +con_toggle` in
`cfg/config_default.cfg`), or `con_show`, `con_show_full`, `con_hide`; `clear`, `help`.
- Opened by the key bound to `toggleconsole` (`bind GRAVE toggleconsole` in
`cfg/config_default.cfg`). `CGameHost::Key_Event` checks this key before any other input
handling, so it works while ImGui has focus; with the console open, Shift + the key toggles the
log view. Also `con_toggle` / `+con_toggle`, `con_show`, `con_show_full`, `con_hide`; `clear`,
`help`.
- Executes console commands (see [framework_core.md](framework_core.md)) with autocompletion,
variants, history and a log view. With the Lua state initialized, input that fails as a command
is executed as Lua (`SetAlternateHandler`, see [scripting_esl_overview.md](scripting_esl_overview.md)).
- ConVars: `con_size`, `con_suggest`, `con_minicon`, `con_minicon_time`.
- The console owns the ImGui frame (`g_imGuiHost`, `shared/imgui_backend`): ImGui windows registered
with `g_imGuiHost->AddDebugHandler` are always drawn, and the debug menu bar with
`AddDebugMenu(path, handler)` entries is shown while the console is open.
- ImGui is run by the host (`g_imGuiHost`, `shared/imgui_backend`), not the console: ImGui
windows registered with `g_imGuiHost->AddDebugHandler` are always drawn, and the debug menu bar
with `AddDebugMenu(path, handler)` entries is shown while the console is open.
- `CEqConsoleInput::SpewInit` captures engine log output for the console log from the start.

## Configuration files
Expand Down
15 changes: 13 additions & 2 deletions docs/tools_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,25 @@ skeleton, animations and sequences, physics objects. Built on `sysLib` with an I
come from `nfd` (`src_dependency/nfd`).

- `-model <path>` opens a model on start.
- The scene is rendered into a `CHostViewport` (see
[sys_application_overview.md](sys_application_overview.md)) shown in the ImGui window between the
model browser and the bottom panel; camera and drag input and hotkeys work while the mouse is over
the scene or the scene window is focused.
- Model browser on the left (View → Model browser) lists `.egf` files under `models/` of the `SP_MOD`
search paths; clicking a file opens it. Directories are scanned when first expanded, Refresh
rescans them. The filter field shows a flat list of files whose names contain the text (case
insensitive); it scans all directories under `models/`.
- File → Compile scripts... runs `egfca` (`.esc`) or `animca` (`.asc`) for the selected scripts and
waits for them. Their stdout and stderr go to the engine console through a pipe (no console window
is opened); a single compiled model is opened afterwards.
- Camera: Shift + left / right / middle mouse button drag rotates, zooms and pans; the cursor wraps
around the window edges while the camera moves. Left button drag pulls physics objects while
around the scene viewport edges while the camera moves. Left button drag pulls physics objects while
physics simulation runs.
- Physics preview runs eqPhysics with a fixed 1/60 s step on a floor box at zero height. All
surface params of the model fall back to one built-in `default` param. Ragdolls
(`ragdoll/physics_ragdoll.*`) use point and angular limit constraints with the joint limits
from the `.pod`; ragdoll parts collide only with the floor.
- Hotkeys: Ctrl+O open, R reset view, P physics objects, B bones, W wireframe.
- Hotkeys (scene window focused): Ctrl+O open, R reset view, P physics objects, B bones, W wireframe.
- Writes its ConVars to `cfg/egfman2.cfg` instead of the game `cfg/user.cfg` unless `-user_cfg` is
given.

Expand Down
Loading
Loading