Class: Doom::Render::SpinelNativeRenderer

Inherits:
Object
  • Object
show all
Defined in:
lib/doom/render/spinel_native_renderer.rb

Overview

Runs the classic software renderer's hot path (BSP -> textured walls -> floors/ceilings -> sky) through spinel_native. The pixel-producing code lives in Doom::Render::SpinelNative::Kernel as native methods that mirror lib/doom/render/renderer.rb one-to-one; this class only flattens the map, textures and flats into the plain Integer/Float arrays the kernel boundary accepts, then calls it once per frame and hands back the framebuffer.

The same kernel methods run as plain Ruby when SPINEL_NATIVE=off, so the port can be verified against the reference renderer before compiling.

Constant Summary collapse

SCREEN_WIDTH =
320
SCREEN_HEIGHT =
240
EYE_HEIGHT =
41

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(map, palette, colormap, textures, flats) ⇒ SpinelNativeRenderer

Returns a new instance of SpinelNativeRenderer.



23
24
25
26
27
28
# File 'lib/doom/render/spinel_native_renderer.rb', line 23

def initialize(map, palette, colormap, textures, flats)
  @map = map
  @palette = palette
  flatten_all(map, colormap, textures, flats)
  upload
end

Instance Attribute Details

#paletteObject (readonly)

Returns the value of attribute palette.



21
22
23
# File 'lib/doom/render/spinel_native_renderer.rb', line 21

def palette
  @palette
end

Instance Method Details

#ceiling_clipObject

Wall-pass outputs from the last render, for the Ruby sprite pass.



52
# File 'lib/doom/render/spinel_native_renderer.rb', line 52

def ceiling_clip = SpinelNative::Kernel.get_cclip

#floor_clipObject



53
# File 'lib/doom/render/spinel_native_renderer.rb', line 53

def floor_clip = SpinelNative::Kernel.get_fclip

#floor_height_at(x, y) ⇒ Object

Eye height follows the floor under the player (classic pz = floorz + 41).



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/doom/render/spinel_native_renderer.rb', line 57

def floor_height_at(x, y)
  ni = @node_count - 1
  while (ni & 0x8000).zero?
    b = ni * 6
    side = (x.to_f - @nodes_f[b]) * @nodes_f[b + 3] >= (y.to_f - @nodes_f[b + 1]) * @nodes_f[b + 2] ? 0 : 1
    ni = (side.zero? ? @nodes_f[b + 4] : @nodes_f[b + 5]).to_i
  end
  first = @subs[(ni & 0x7FFF) * 2]
  sdi = @lines[@segs[first * 5 + 2] * 3 + (@segs[first * 5 + 3].zero? ? 0 : 1)]
  @secs[@sides[sdi * 6] * 6]
end

#render(px, py, angle_rad) ⇒ Object

Render one frame from the given eye pose. Returns a 76800-int framebuffer of palette indices (row-major, 320x240).



40
41
42
43
# File 'lib/doom/render/spinel_native_renderer.rb', line 40

def render(px, py, angle_rad)
  pz = floor_height_at(px, py) + EYE_HEIGHT
  SpinelNative::Kernel.render(px.round, py.round, pz, angle_rad)
end

#render_at(px, py, pz, angle_rad) ⇒ Object

Render with an explicit eye height (the game supplies player_z), for integration into the real Renderer.



47
48
49
# File 'lib/doom/render/spinel_native_renderer.rb', line 47

def render_at(px, py, pz, angle_rad)
  SpinelNative::Kernel.render(px.round, py.round, pz.round, angle_rad)
end

#uploadObject

Upload the flattened map/textures into the kernel's state once.



31
32
33
34
35
36
# File 'lib/doom/render/spinel_native_renderer.rb', line 31

def upload
  SpinelNative::Kernel.load_map(
    @nodes_f, @verts, @segs, @subs, @lines, @sides, @secs,
    @wpx, @wtab, @fpx, @cmap, @node_count, @sky_tex
  )
end

#wall_depthObject



54
# File 'lib/doom/render/spinel_native_renderer.rb', line 54

def wall_depth = SpinelNative::Kernel.get_wdepth