Module: Doom::Platform::SDLDisplayMode

Defined in:
lib/doom/platform/sdl.rb

Overview

Ask SDL for the display's refresh rate.

Timing our own buffer swaps cannot answer this: when the engine renders slower than the display refreshes -- which is the normal case here -- the swap cadence measures our render time, not the monitor. SDL knows the real number, and Gosu bundles SDL, so we read it directly the same way SDLKeyboardGrab reaches for SDL_SetWindowKeyboardGrab.

Constant Summary collapse

REFRESH_RATE_OFFSET =

SDL_DisplayMode { Uint32 format; int w; int h; int refresh_rate; void *driverdata; }

12
STRUCT_SIZE =
32

Class Method Summary collapse

Class Method Details

.refresh_rateObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/doom/platform/sdl.rb', line 51

def self.refresh_rate
  require 'fiddle'
  gosu_spec = Gem.loaded_specs['gosu']
  lib_ext = RbConfig::CONFIG['DLEXT'] || 'so'
  lib = Fiddle.dlopen(File.join(gosu_spec.full_gem_path, 'lib', "gosu.#{lib_ext}"))

  get_mode = Fiddle::Function.new(
    lib['SDL_GetCurrentDisplayMode'],
    [Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT
  )

  buf = Fiddle::Pointer.malloc(STRUCT_SIZE)
  return nil unless get_mode.call(0, buf).zero?

  hz = buf[REFRESH_RATE_OFFSET, 4].unpack1('l')
  # SDL reports 0 when the rate is unspecified (some virtual displays).
  hz.positive? ? hz : nil
rescue StandardError, LoadError => e
  warn "SDLDisplayMode.refresh_rate failed: #{e.class}: #{e.message}"
  nil
end