Skip to content
Open
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
50 changes: 50 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Documentation

on:
push:
branches: [master]
paths:
- 'game/**'
- 'docs/**'
- 'Doxyfile'
- '.github/workflows/docs.yml'
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Doxygen
run: sudo apt-get update && sudo apt-get install -y doxygen

- name: Generate documentation
run: doxygen Doxyfile

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/html

deploy:
needs: build
runs-on: ubuntu-24.04
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@ out/*
.vs/
internal/

#os
# os
.DS_Store

# Doxigen
docs/html/
45 changes: 45 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Doxyfile for OpenGothic

PROJECT_NAME = "OpenGothic"
PROJECT_BRIEF = "Open source reimplementation of Gothic I and II"
OUTPUT_DIRECTORY = docs

# Input
INPUT = game docs/mainpage.md
FILE_PATTERNS = *.cpp *.h *.hpp *.md
USE_MDFILE_AS_MAINPAGE = docs/mainpage.md
RECURSIVE = YES
EXCLUDE_PATTERNS = */lib/*

# Output
GENERATE_HTML = YES
GENERATE_LATEX = NO
GENERATE_TREEVIEW = YES
DISABLE_INDEX = NO
FULL_SIDEBAR = NO
HTML_COLORSTYLE = LIGHT

# doxygen-awesome-css
HTML_EXTRA_STYLESHEET = lib/doxygen-awesome-css/doxygen-awesome.css \
lib/doxygen-awesome-css/doxygen-awesome-sidebar-only.css \
lib/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css
HTML_EXTRA_FILES = lib/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js \
lib/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js \
lib/doxygen-awesome-css/doxygen-awesome-paragraph-link.js

# Extraction
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES

# Source browsing
SOURCE_BROWSER = YES
INLINE_SOURCES = NO

# Graphs (requires graphviz)
HAVE_DOT = NO
CLASS_DIAGRAMS = YES

# Warnings
WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = YES
19 changes: 19 additions & 0 deletions docs/mainpage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# OpenGothic Documentation {#mainpage}

This is the API documentation for OpenGothic, an open source reimplementation of Gothic I and II.

## Source Structure

- @ref MainWindow - Application entry point and render loop
- **game/** - Core game logic and session management
- **graphics/** - Rendering pipeline
- **world/** - World, NPCs, and game objects
- **ui/** - Menus and HUD

## Building the Docs

```
doxygen Doxyfile
```

Output is generated in `docs/html/`.
66 changes: 54 additions & 12 deletions game/mainwindow.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* @file mainwindow.h
* @brief Main application window for OpenGothic
*/

#pragma once

#include "camera.h"
Expand Down Expand Up @@ -42,14 +47,33 @@ class MenuRoot;
class GameSession;
class Interactive;

/**
* @brief Main application window handling game rendering and input
*
* MainWindow is the primary window class that manages the game's rendering loop,
* user input handling, UI composition, and game state transitions. It coordinates
* between the renderer, game session, and various UI components (menus, dialogs,
* inventory, etc.).
*/
class MainWindow : public Tempest::Window {
public:
/**
* @brief Constructs the main window
* @param device The graphics device used for rendering
*/
explicit MainWindow(Tempest::Device& device);

~MainWindow() override;

/**
* @brief Returns the current UI scaling factor
* @return Scale factor based on system DPI settings
*/
float uiScale() const;

private:
/// @name Event Handlers
/// @{
void paintEvent (Tempest::PaintEvent& event) override;
void resizeEvent (Tempest::SizeEvent & event) override;

Expand All @@ -64,7 +88,10 @@ class MainWindow : public Tempest::Window {
void keyUpEvent (Tempest::KeyEvent& event) override;

void focusEvent (Tempest::FocusEvent& event) override;
/// @}

/// @name Drawing Helpers
/// @{
void paintFocus (Tempest::Painter& p, const Focus& fc, const Tempest::Matrix4x4& vp);
void paintFocus (Tempest::Painter& p, Tempest::Rect rect);

Expand All @@ -74,10 +101,14 @@ class MainWindow : public Tempest::Window {
void drawLoading (Tempest::Painter& p,int x,int y,int w,int h);
void drawSaving (Tempest::Painter& p);
void drawSaving (Tempest::Painter& p, const Tempest::Texture2d& back, int w, int h, float scale);
/// @}

void startGame(std::string_view slot);
void loadGame (std::string_view slot);
void saveGame (std::string_view slot, std::string_view name);
/// @name Game Session Control
/// @{
void startGame(std::string_view slot); ///< Start a new game from the given world slot
void loadGame (std::string_view slot); ///< Load a saved game from the given slot
void saveGame (std::string_view slot, std::string_view name); ///< Save current game to slot
/// @}

void onVideo(std::string_view fname);
void onStartLoading();
Expand Down Expand Up @@ -106,10 +137,13 @@ class MainWindow : public Tempest::Window {

Camera::Mode solveCameraMode() const;

/**
* @brief Runtime execution mode for debugging
*/
enum RuntimeMode : uint8_t {
R_Normal,
R_Suspended,
R_Step,
R_Normal, ///< Normal game execution
R_Suspended, ///< Game logic paused (Marvin mode)
R_Step, ///< Single-step execution
};

Tempest::Device& device;
Expand Down Expand Up @@ -163,19 +197,27 @@ class MainWindow : public Tempest::Window {
Tempest::Shortcut funcKey[11];
Tempest::Shortcut displayPos;

/**
* @brief Stores benchmark metrics for performance analysis
*/
struct BenchmarkData {
std::vector<uint64_t> low1procent;
std::vector<uint64_t> low1procent; ///< Frame times for lowest 1% calculation
size_t numFrames = 0;
double fpsSum = 0;
void push(uint64_t t);
void clear();
};

/**
* @brief Rolling FPS counter using last 10 frame times
*/
struct Fps {
uint64_t dt[10]={};
double get() const;
uint64_t dt[10]={}; ///< Ring buffer of frame delta times
double get() const; ///< Calculate average FPS
void push(uint64_t t);
};
Fps fps;
BenchmarkData benchmark;
uint64_t maxFpsInv = 0;

Fps fps; ///< Current FPS tracker
BenchmarkData benchmark; ///< Benchmark data collector
uint64_t maxFpsInv = 0; ///< Inverse of max FPS limit (ms per frame)
};
Loading