Module: Doom::Platform::WindowLogic
- Defined in:
- lib/doom/platform/window_logic.rb
Overview
Pure helpers extracted from GosuWindow so they can be tested without a display. GosuWindow subclasses Gosu::Window, which cannot be loaded (let alone instantiated) under RSpec, so any decision logic worth testing lives here as plain functions and GosuWindow just delegates to them.
Constant Summary collapse
- SKILL_FLAG_EASY =
DOOM thing flags: bit 0 = skill 1-2 (baby/easy), bit 1 = skill 3 (medium), bit 2 = skill 4-5 (hard/nightmare), bit 4 = multiplayer-only.
0x0001- SKILL_FLAG_MEDIUM =
0x0002- SKILL_FLAG_HARD =
0x0004- MULTIPLAYER_ONLY_FLAG =
0x0010
Class Method Summary collapse
-
.net_status_lines(started:, host:, waiting:, stalled_seconds:, stall_threshold:, desync: nil) ⇒ Object
Net status overlay lines.
-
.present_due?(now_ms, last_present_ms, interval_ms, slack) ⇒ Boolean
Frame-presentation cadence.
-
.skill_flag_bit(skill) ⇒ Object
The flag bit a thing must carry to appear at the given skill.
-
.skill_hidden(skill, things) ⇒ Object
Which things this skill hides.
Class Method Details
.net_status_lines(started:, host:, waiting:, stalled_seconds:, stall_threshold:, desync: nil) ⇒ Object
Net status overlay lines. A lockstep stall under the threshold is normal -- every peer briefly waits for the next command between tics -- so it produces nothing; only a stall past the threshold, a session that has not started yet, or a desync is worth interrupting the player for.
51 52 53 54 55 56 57 58 |
# File 'lib/doom/platform/window_logic.rb', line 51 def self.net_status_lines(started:, host:, waiting:, stalled_seconds:, stall_threshold:, desync: nil) lines = [] lines << (host ? 'WAITING FOR PLAYERS' : 'CONNECTING...') unless started lines << "WAITING FOR PLAYER #{waiting.join(', ')}" if waiting.any? && stalled_seconds > stall_threshold lines << "DESYNC AT TIC #{desync.tic} (#{Array(desync.sections).join(', ')})" if desync lines end |
.present_due?(now_ms, last_present_ms, interval_ms, slack) ⇒ Boolean
Frame-presentation cadence. Rendering runs every loop iteration, but we only blit/swap once a refresh interval (minus slack, so we aim slightly before vblank) has elapsed since the last present.
43 44 45 |
# File 'lib/doom/platform/window_logic.rb', line 43 def self.present_due?(now_ms, last_present_ms, interval_ms, slack) (now_ms - last_present_ms) >= (interval_ms * slack) end |
.skill_flag_bit(skill) ⇒ Object
The flag bit a thing must carry to appear at the given skill. skill uses Game::Menu::SKILL_* values (0-4).
19 20 21 22 23 24 25 26 |
# File 'lib/doom/platform/window_logic.rb', line 19 def self.skill_flag_bit(skill) case skill when Game::Menu::SKILL_BABY, Game::Menu::SKILL_EASY then SKILL_FLAG_EASY when Game::Menu::SKILL_MEDIUM then SKILL_FLAG_MEDIUM when Game::Menu::SKILL_HARD, Game::Menu::SKILL_NIGHTMARE then SKILL_FLAG_HARD else SKILL_FLAG_EASY | SKILL_FLAG_MEDIUM | SKILL_FLAG_HARD end end |
.skill_hidden(skill, things) ⇒ Object
Which things this skill hides. A thing is hidden if it is multiplayer-only, or if it does not carry the flag bit for this skill. Returns { index => true } (matching the world's skill_hidden shape).
31 32 33 34 35 36 37 38 |
# File 'lib/doom/platform/window_logic.rb', line 31 def self.skill_hidden(skill, things) flag_bit = skill_flag_bit(skill) hidden = {} things.each_with_index do |thing, idx| hidden[idx] = true if (thing.flags & MULTIPLAYER_ONLY_FLAG) != 0 || (thing.flags & flag_bit) == 0 end hidden end |