doom 0.8.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +17 -0
- data/README.md +65 -4
- data/bin/doom +134 -24
- data/lib/doom/benchmark.rb +282 -0
- data/lib/doom/game/animations.rb +9 -2
- data/lib/doom/game/combat.rb +239 -153
- data/lib/doom/game/framebuffer_blitter.rb +38 -0
- data/lib/doom/game/geometry.rb +68 -0
- data/lib/doom/game/intermission.rb +22 -39
- data/lib/doom/game/item_pickup.rb +87 -75
- data/lib/doom/game/menu.rb +90 -85
- data/lib/doom/game/monster_ai.rb +150 -136
- data/lib/doom/game/player.rb +105 -0
- data/lib/doom/game/player_physics.rb +384 -0
- data/lib/doom/game/player_state.rb +38 -64
- data/lib/doom/game/random.rb +82 -0
- data/lib/doom/game/sector_actions.rb +169 -93
- data/lib/doom/game/sector_effects.rb +25 -18
- data/lib/doom/game/snapshot.rb +584 -0
- data/lib/doom/game/sound_engine.rb +33 -58
- data/lib/doom/game/state_hash.rb +125 -0
- data/lib/doom/game/ticcmd.rb +61 -0
- data/lib/doom/game/world.rb +420 -0
- data/lib/doom/map/data.rb +95 -0
- data/lib/doom/net/client.rb +204 -0
- data/lib/doom/net/desync_monitor.rb +101 -0
- data/lib/doom/net/game_server.rb +232 -0
- data/lib/doom/net/lockstep.rb +170 -0
- data/lib/doom/net/protocol.rb +350 -0
- data/lib/doom/net/session.rb +282 -0
- data/lib/doom/net/transport.rb +110 -0
- data/lib/doom/platform/gosu_window.rb +604 -832
- data/lib/doom/platform/sdl.rb +74 -0
- data/lib/doom/platform/window_logic.rb +61 -0
- data/lib/doom/render/font.rb +5 -3
- data/lib/doom/render/hardware_renderer.rb +547 -0
- data/lib/doom/render/ray_tracing/bvh.rb +103 -0
- data/lib/doom/render/ray_tracing/material_state.rb +66 -0
- data/lib/doom/render/ray_tracing/texture_atlas.rb +78 -0
- data/lib/doom/render/ray_tracing_renderer.rb +940 -0
- data/lib/doom/render/renderer.rb +466 -440
- data/lib/doom/render/renderer_factory.rb +50 -0
- data/lib/doom/render/screen_melt.rb +7 -7
- data/lib/doom/render/spinel_native/kernel.rb +780 -0
- data/lib/doom/render/spinel_native_renderer.rb +162 -0
- data/lib/doom/render/status_bar.rb +14 -10
- data/lib/doom/render/weapon_renderer.rb +9 -10
- data/lib/doom/render/world_mesh.rb +270 -0
- data/lib/doom/render/zbuffer_renderer.rb +151 -0
- data/lib/doom/version.rb +1 -1
- data/lib/doom/wad/flat.rb +1 -1
- data/lib/doom/wad/hud_graphics.rb +7 -3
- data/lib/doom/wad/palette.rb +3 -3
- data/lib/doom/wad/patch.rb +1 -1
- data/lib/doom/wad/reader.rb +12 -15
- data/lib/doom/wad/sound.rb +14 -6
- data/lib/doom/wad/sprite.rb +36 -35
- data/lib/doom/wad/texture.rb +5 -5
- data/lib/doom/wad_downloader.rb +38 -56
- data/lib/doom.rb +197 -16
- metadata +94 -7
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Doom
|
|
4
|
+
module Render
|
|
5
|
+
module RayTracing
|
|
6
|
+
# Resolves animated WAD materials and packs per-surface flags into the
|
|
7
|
+
# float shared with sector light level in the GPU triangle texture.
|
|
8
|
+
class MaterialState
|
|
9
|
+
EMISSIVE_FLAG = 1_024.0
|
|
10
|
+
MASKED_FLAG = 2_048.0
|
|
11
|
+
REFLECTIVE_FLAG = 4_096.0
|
|
12
|
+
REFRACTIVE_FLAG = 8_192.0
|
|
13
|
+
EMISSIVE_PATTERN = /\A(?:NUKAGE|SLIME|LAVA)/
|
|
14
|
+
LIQUID_PATTERN = /\A(?:NUKAGE|SLIME|LAVA|FWATER|SWATER|BLOOD)/
|
|
15
|
+
REFLECTIVE_PATTERN = /#{LIQUID_PATTERN.source}|(?:METAL|SILVER|COMP|TEK|SUPPORT)/
|
|
16
|
+
REFRACTIVE_PATTERN = LIQUID_PATTERN
|
|
17
|
+
|
|
18
|
+
def initialize(flats, animations)
|
|
19
|
+
@flats = flats
|
|
20
|
+
@animations = animations
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def animation_signature
|
|
24
|
+
return nil unless @animations
|
|
25
|
+
|
|
26
|
+
[@animations.flat_translation.values, @animations.texture_translation.values]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def animation_names
|
|
30
|
+
return [] unless @animations
|
|
31
|
+
return @animations.frame_names if @animations.respond_to?(:frame_names)
|
|
32
|
+
|
|
33
|
+
[@animations.flat_translation, @animations.texture_translation]
|
|
34
|
+
.flat_map { |translation| translation.keys + translation.values }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def resolve(name)
|
|
38
|
+
return name unless @animations
|
|
39
|
+
|
|
40
|
+
@flats.key?(name) ? @animations.translate_flat(name) : @animations.translate_texture(name)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def emissive?(name)
|
|
44
|
+
name&.match?(EMISSIVE_PATTERN) || false
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def reflective?(name)
|
|
48
|
+
name&.match?(REFLECTIVE_PATTERN) || false
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def refractive?(name)
|
|
52
|
+
name&.match?(REFRACTIVE_PATTERN) || false
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def encoded_light(triangle)
|
|
56
|
+
value = triangle.light.to_f
|
|
57
|
+
value += EMISSIVE_FLAG if emissive?(triangle.material)
|
|
58
|
+
value += MASKED_FLAG if triangle.masked
|
|
59
|
+
value += REFLECTIVE_FLAG if reflective?(triangle.material)
|
|
60
|
+
value += REFRACTIVE_FLAG if refractive?(triangle.material)
|
|
61
|
+
value
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Doom
|
|
4
|
+
module Render
|
|
5
|
+
module RayTracing
|
|
6
|
+
# Packs palette-indexed flats and composite wall textures into one RGBA
|
|
7
|
+
# texture. Rectangle entries are [x, y, width, height, texel_w, texel_h].
|
|
8
|
+
class TextureAtlas
|
|
9
|
+
attr_reader :size
|
|
10
|
+
|
|
11
|
+
def initialize(size:, textures:, flats:, palette:)
|
|
12
|
+
@size = size
|
|
13
|
+
@textures = textures
|
|
14
|
+
@flats = flats
|
|
15
|
+
@palette = palette
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def build(material_names)
|
|
19
|
+
pixels = "\0" * (@size * @size * 4)
|
|
20
|
+
rectangles = {}
|
|
21
|
+
x = y = row_height = 0
|
|
22
|
+
material_names.uniq.each do |name|
|
|
23
|
+
source = source_for(name)
|
|
24
|
+
next unless source
|
|
25
|
+
|
|
26
|
+
width, height, rgba = source
|
|
27
|
+
if x + width > @size
|
|
28
|
+
x = 0
|
|
29
|
+
y += row_height
|
|
30
|
+
row_height = 0
|
|
31
|
+
end
|
|
32
|
+
raise ArgumentError, 'ray texture atlas overflow' if y + height > @size
|
|
33
|
+
|
|
34
|
+
height.times do |row|
|
|
35
|
+
destination = (((y + row) * @size) + x) * 4
|
|
36
|
+
pixels[destination, width * 4] = rgba.byteslice(row * width * 4, width * 4)
|
|
37
|
+
end
|
|
38
|
+
rectangles[name] = [x.to_f / @size, y.to_f / @size,
|
|
39
|
+
width.to_f / @size, height.to_f / @size,
|
|
40
|
+
width.to_f, height.to_f]
|
|
41
|
+
x += width
|
|
42
|
+
row_height = [row_height, height].max
|
|
43
|
+
end
|
|
44
|
+
[pixels, rectangles]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def source_for(name)
|
|
50
|
+
source = @flats[name] || @textures[name]
|
|
51
|
+
return unless source
|
|
52
|
+
|
|
53
|
+
width = source.width
|
|
54
|
+
height = source.height
|
|
55
|
+
indices = if source.respond_to?(:column_pixels)
|
|
56
|
+
columns_to_rows(source, width, height)
|
|
57
|
+
else
|
|
58
|
+
source.pixels
|
|
59
|
+
end
|
|
60
|
+
rgba = indices.map do |index|
|
|
61
|
+
index.nil? ? "\0\0\0\0" : [*@palette.colors[index], 255].pack('C4')
|
|
62
|
+
end.join
|
|
63
|
+
[width, height, rgba]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def columns_to_rows(source, width, height)
|
|
67
|
+
pixels = Array.new(width * height)
|
|
68
|
+
width.times do |column|
|
|
69
|
+
source.column_pixels(column).each_with_index do |value, row|
|
|
70
|
+
pixels[(row * width) + column] = value if row < height
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
pixels
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|