doom 0.2.0 → 0.4.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.
metadata CHANGED
@@ -1,57 +1,59 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hasinski
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-03-06 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
- name: rake
14
+ name: gosu
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
- version: '13.0'
19
- type: :development
19
+ version: '1.4'
20
+ type: :runtime
20
21
  prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
24
  - - "~>"
24
25
  - !ruby/object:Gem::Version
25
- version: '13.0'
26
+ version: '1.4'
26
27
  - !ruby/object:Gem::Dependency
27
- name: minitest
28
+ name: rspec
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: '5.0'
33
+ version: '3.12'
33
34
  type: :development
34
35
  prerelease: false
35
36
  version_requirements: !ruby/object:Gem::Requirement
36
37
  requirements:
37
38
  - - "~>"
38
39
  - !ruby/object:Gem::Version
39
- version: '5.0'
40
+ version: '3.12'
40
41
  - !ruby/object:Gem::Dependency
41
- name: gosu
42
+ name: chunky_png
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - "~>"
45
46
  - !ruby/object:Gem::Version
46
47
  version: '1.4'
47
- type: :runtime
48
+ type: :development
48
49
  prerelease: false
49
50
  version_requirements: !ruby/object:Gem::Requirement
50
51
  requirements:
51
52
  - - "~>"
52
53
  - !ruby/object:Gem::Version
53
54
  version: '1.4'
54
- description: Ruby Doom is a Ruby gem that ports the classic Doom game to Ruby
55
+ description: A faithful port of the Doom (1993) rendering engine to Ruby. Supports
56
+ original WAD files with near pixel-perfect BSP rendering.
55
57
  email:
56
58
  - krzysztof.hasinski@gmail.com
57
59
  executables:
@@ -59,32 +61,31 @@ executables:
59
61
  extensions: []
60
62
  extra_rdoc_files: []
61
63
  files:
62
- - LICENSE.txt
63
64
  - README.md
64
- - bin/console
65
65
  - bin/doom
66
- - bin/setup
67
- - bin/wad
68
66
  - lib/doom.rb
69
- - lib/doom/bsp_renderer.rb
70
- - lib/doom/game.rb
71
- - lib/doom/hud.rb
72
- - lib/doom/map_loader.rb
73
- - lib/doom/renderer.rb
74
- - lib/doom/sprite_loader.rb
75
- - lib/doom/sprite_renderer.rb
76
- - lib/doom/texture_loader.rb
77
- - lib/doom/texture_mapper.rb
67
+ - lib/doom/game/player_state.rb
68
+ - lib/doom/game/sector_actions.rb
69
+ - lib/doom/map/data.rb
70
+ - lib/doom/platform/gosu_window.rb
71
+ - lib/doom/render/renderer.rb
72
+ - lib/doom/render/status_bar.rb
73
+ - lib/doom/render/weapon_renderer.rb
78
74
  - lib/doom/version.rb
79
- - lib/doom/wad_loader.rb
80
- - lib/doom/window.rb
75
+ - lib/doom/wad/colormap.rb
76
+ - lib/doom/wad/flat.rb
77
+ - lib/doom/wad/hud_graphics.rb
78
+ - lib/doom/wad/palette.rb
79
+ - lib/doom/wad/patch.rb
80
+ - lib/doom/wad/reader.rb
81
+ - lib/doom/wad/sprite.rb
82
+ - lib/doom/wad/texture.rb
83
+ - lib/doom/wad_downloader.rb
81
84
  homepage: https://github.com/khasinski/doom-rb
82
85
  licenses:
83
- - MIT
84
- metadata:
85
- homepage_uri: https://github.com/khasinski/doom-rb
86
- source_code_uri: https://github.com/khasinski/doom-rb
87
- changelog_uri: https://github.com/khasinski/doom-rb/blob/master/CHANGELOG.md
86
+ - GPL-2.0
87
+ metadata: {}
88
+ post_install_message:
88
89
  rdoc_options: []
89
90
  require_paths:
90
91
  - lib
@@ -92,14 +93,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
93
  requirements:
93
94
  - - ">="
94
95
  - !ruby/object:Gem::Version
95
- version: 2.6.0
96
+ version: '3.1'
96
97
  required_rubygems_version: !ruby/object:Gem::Requirement
97
98
  requirements:
98
99
  - - ">="
99
100
  - !ruby/object:Gem::Version
100
101
  version: '0'
101
102
  requirements: []
102
- rubygems_version: 3.6.8
103
+ rubygems_version: 3.5.22
104
+ signing_key:
103
105
  specification_version: 4
104
- summary: A Ruby port of the classic Doom game
106
+ summary: Doom engine port in pure Ruby
105
107
  test_files: []
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2023 Chris Hasiński
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "doom"
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other setup tasks here
data/bin/wad DELETED
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "doom"
6
- require "optparse"
7
-
8
- options = {
9
- action: nil,
10
- map: nil,
11
- texture: nil,
12
- sprite: nil
13
- }
14
-
15
- parser = OptionParser.new do |opts|
16
- opts.banner = "Usage: wad [options] WAD_FILE"
17
-
18
- opts.on("-l", "--list-maps", "List all maps in the WAD file") do
19
- options[:action] = :list_maps
20
- end
21
-
22
- opts.on("-m", "--map MAP", "Show details for a specific map") do |map|
23
- options[:action] = :show_map
24
- options[:map] = map
25
- end
26
-
27
- opts.on("-t", "--list-textures", "List all textures in the WAD file") do
28
- options[:action] = :list_textures
29
- end
30
-
31
- opts.on("-x", "--texture TEXTURE", "Show details for a specific texture") do |texture|
32
- options[:action] = :show_texture
33
- options[:texture] = texture
34
- end
35
-
36
- opts.on("-s", "--list-sprites", "List all sprites in the WAD file") do
37
- options[:action] = :list_sprites
38
- end
39
-
40
- opts.on("-p", "--sprite SPRITE", "Show details for a specific sprite") do |sprite|
41
- options[:action] = :show_sprite
42
- options[:sprite] = sprite
43
- end
44
-
45
- opts.on("-i", "--info", "Show general information about the WAD file") do
46
- options[:action] = :show_info
47
- end
48
-
49
- opts.on("-h", "--help", "Show this help message") do
50
- puts opts
51
- exit
52
- end
53
- end
54
-
55
- parser.parse!
56
-
57
- if ARGV.empty?
58
- puts "Error: WAD file is required"
59
- puts parser
60
- exit 1
61
- end
62
-
63
- wad_file = ARGV[0]
64
- unless File.exist?(wad_file)
65
- puts "Error: WAD file '#{wad_file}' not found"
66
- exit 1
67
- end
68
-
69
- begin
70
- loaders = Doom.load_wad(wad_file)
71
-
72
- case options[:action]
73
- when :list_maps
74
- puts "Maps in #{wad_file}:"
75
- loaders[:maps].maps.each do |map|
76
- puts " #{map}"
77
- end
78
-
79
- when :show_map
80
- map_name = options[:map]
81
- if loaders[:maps].maps.include?(map_name)
82
- map_data = loaders[:maps].load_map(map_name)
83
- puts "Map: #{map_name}"
84
- puts " Things: #{map_data[:things].size}"
85
- puts " Linedefs: #{map_data[:linedefs].size}"
86
- puts " Sidedefs: #{map_data[:sidedefs].size}"
87
- puts " Vertexes: #{map_data[:vertexes].size}"
88
- puts " Sectors: #{map_data[:sectors].size}"
89
- else
90
- puts "Error: Map '#{map_name}' not found"
91
- exit 1
92
- end
93
-
94
- when :list_textures
95
- puts "Textures in #{wad_file}:"
96
- loaders[:textures].texture_names.each do |texture|
97
- puts " #{texture}"
98
- end
99
-
100
- when :show_texture
101
- texture_name = options[:texture]
102
- if loaders[:textures].texture_exists?(texture_name)
103
- texture_data = loaders[:textures].get_texture(texture_name)
104
- puts "Texture: #{texture_name}"
105
- puts " Width: #{texture_data[:width]}"
106
- puts " Height: #{texture_data[:height]}"
107
- puts " Patches: #{texture_data[:patches].size}"
108
- texture_data[:patches].each_with_index do |patch, i|
109
- puts " Patch #{i + 1}: #{patch[:patch_name]} (#{patch[:x_offset]}, #{patch[:y_offset]})"
110
- end
111
- else
112
- puts "Error: Texture '#{texture_name}' not found"
113
- exit 1
114
- end
115
-
116
- when :list_sprites
117
- puts "Sprites in #{wad_file}:"
118
- loaders[:sprites].sprite_names.each do |sprite|
119
- puts " #{sprite}"
120
- end
121
-
122
- when :show_sprite
123
- sprite_name = options[:sprite]
124
- if loaders[:sprites].sprite_exists?(sprite_name)
125
- sprite_data = loaders[:sprites].get_sprite(sprite_name)
126
- puts "Sprite: #{sprite_name}"
127
- puts " Width: #{sprite_data[:width]}"
128
- puts " Height: #{sprite_data[:height]}"
129
- puts " Offset: (#{sprite_data[:left_offset]}, #{sprite_data[:top_offset]})"
130
- else
131
- puts "Error: Sprite '#{sprite_name}' not found"
132
- exit 1
133
- end
134
-
135
- when :show_info
136
- puts "WAD File: #{wad_file}"
137
- puts "Type: #{loaders[:wad].wad_type}"
138
- puts "Directory entries: #{loaders[:wad].directory.size}"
139
- puts "Lumps: #{loaders[:wad].lumps.size}"
140
- puts "Maps: #{loaders[:maps].maps.size}"
141
- puts "Textures: #{loaders[:textures].texture_names.size}"
142
- puts "Sprites: #{loaders[:sprites].sprite_names.size}"
143
-
144
- else
145
- puts "Please specify an action. Use --help for options."
146
- exit 1
147
- end
148
-
149
- rescue Doom::Error => e
150
- puts "Error: #{e.message}"
151
- exit 1
152
- end
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Doom
4
- # BSPRenderer is responsible for rendering the level using Binary Space Partitioning
5
- class BSPRenderer < Renderer
6
- attr_reader :map_loader
7
-
8
- # Initialize a new BSPRenderer with the given window and map loader
9
- # @param window [Doom::Window] the window to render to
10
- # @param map_loader [Doom::MapLoader] the map loader to use
11
- def initialize(window, map_loader)
12
- super(window)
13
- @map_loader = map_loader
14
- @current_map = nil
15
- end
16
-
17
- # Load a specific map
18
- # @param map_name [String] the name of the map to load
19
- def load_map(map_name)
20
- @current_map = @map_loader.load_map(map_name)
21
- end
22
-
23
- # Render the current map
24
- def render
25
- return unless @current_map
26
-
27
- # In a real implementation, this would:
28
- # 1. Determine the player's position and angle
29
- # 2. Traverse the BSP tree to find visible walls
30
- # 3. Render the walls with texture mapping
31
- # 4. Render sprites (enemies, items, etc.)
32
-
33
- # For now, we'll just render a simple wireframe of the map
34
- render_wireframe
35
- end
36
-
37
- private
38
-
39
- # Render a simple wireframe of the map
40
- def render_wireframe
41
- # Get the vertexes and linedefs from the current map
42
- vertexes = @current_map[:vertexes]
43
- linedefs = @current_map[:linedefs]
44
-
45
- # Calculate scale and offset to fit the map in the window
46
- scale, offset_x, offset_y = calculate_scale_and_offset(vertexes)
47
-
48
- # Draw each linedef as a line
49
- linedefs.each do |linedef|
50
- start_vertex = vertexes[linedef[:start_vertex]]
51
- end_vertex = vertexes[linedef[:end_vertex]]
52
-
53
- # Transform the vertexes to screen coordinates
54
- x1 = offset_x + start_vertex[:x] * scale
55
- y1 = offset_y + start_vertex[:y] * scale
56
- x2 = offset_x + end_vertex[:x] * scale
57
- y2 = offset_y + end_vertex[:y] * scale
58
-
59
- # Draw the line
60
- @window.draw_line(x1, y1, Gosu::Color::WHITE, x2, y2, Gosu::Color::WHITE)
61
- end
62
- end
63
-
64
- # Calculate the scale and offset to fit the map in the window
65
- # @param vertexes [Array<Hash>] the vertexes of the map
66
- # @return [Array<Float, Float, Float>] the scale, offset_x, and offset_y
67
- def calculate_scale_and_offset(vertexes)
68
- # Find the min and max coordinates
69
- min_x = vertexes.map { |v| v[:x] }.min
70
- max_x = vertexes.map { |v| v[:x] }.max
71
- min_y = vertexes.map { |v| v[:y] }.min
72
- max_y = vertexes.map { |v| v[:y] }.max
73
-
74
- # Calculate the width and height of the map
75
- map_width = max_x - min_x
76
- map_height = max_y - min_y
77
-
78
- # Calculate the scale to fit the map in the window
79
- scale_x = @window.width * 0.8 / map_width
80
- scale_y = @window.height * 0.8 / map_height
81
- scale = [scale_x, scale_y].min
82
-
83
- # Calculate the offset to center the map
84
- offset_x = (@window.width - map_width * scale) / 2 - min_x * scale
85
- offset_y = (@window.height - map_height * scale) / 2 - min_y * scale
86
-
87
- [scale, offset_x, offset_y]
88
- end
89
- end
90
- end
data/lib/doom/game.rb DELETED
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Doom
4
- # Game is the main class that ties everything together
5
- class Game
6
- attr_reader :window, :loaders, :renderers
7
-
8
- # Initialize a new Game with the given WAD file
9
- # @param wad_file [String] the path to the WAD file
10
- # @param width [Integer] the width of the window
11
- # @param height [Integer] the height of the window
12
- # @param fullscreen [Boolean] whether the window should be fullscreen
13
- def initialize(wad_file, width = 640, height = 480, fullscreen = false)
14
- @wad_file = wad_file
15
- @width = width
16
- @height = height
17
- @fullscreen = fullscreen
18
- @loaders = {}
19
- @renderers = {}
20
- @current_map = nil
21
- @player_data = {
22
- health: 100,
23
- armor: 0,
24
- ammo: 50,
25
- weapon: "Pistol"
26
- }
27
- end
28
-
29
- # Start the game
30
- # @param map_name [String] the name of the map to start on
31
- def start(map_name = nil)
32
- load_wad
33
- setup_window
34
- setup_renderers
35
- load_map(map_name) if map_name
36
- @window.show
37
- end
38
-
39
- # Load the WAD file
40
- def load_wad
41
- @loaders = Doom.load_wad(@wad_file)
42
- end
43
-
44
- # Setup the window
45
- def setup_window
46
- @window = Window.new(@width, @height, @fullscreen)
47
- @window.game = self
48
- end
49
-
50
- # Setup the renderers
51
- def setup_renderers
52
- @renderers[:bsp] = BSPRenderer.new(@window, @loaders[:maps])
53
- @renderers[:texture] = TextureMapper.new(@loaders[:textures])
54
- @renderers[:sprite] = SpriteRenderer.new(@loaders[:sprites])
55
- @renderers[:hud] = HUD.new(@window)
56
- end
57
-
58
- # Load a specific map
59
- # @param map_name [String] the name of the map to load
60
- def load_map(map_name)
61
- @current_map = map_name
62
- @renderers[:bsp].load_map(map_name)
63
- end
64
-
65
- # Update the game state
66
- def update
67
- # Will be implemented in Phase 3
68
- end
69
-
70
- # Draw the game
71
- def draw
72
- @renderers[:bsp].render if @current_map
73
- @renderers[:hud].render(@player_data)
74
- end
75
-
76
- # Handle button press events
77
- def button_down(id)
78
- case id
79
- when Gosu::KB_ESCAPE
80
- @window.close
81
- end
82
- end
83
- end
84
- end
data/lib/doom/hud.rb DELETED
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Doom
4
- # HUD is responsible for rendering the Heads-Up Display
5
- class HUD
6
- attr_reader :window
7
-
8
- # Initialize a new HUD with the given window
9
- # @param window [Doom::Window] the window to render to
10
- def initialize(window)
11
- @window = window
12
- @font = Gosu::Font.new(20)
13
- end
14
-
15
- # Render the HUD
16
- # @param player_data [Hash] the player data to display
17
- def render(player_data = {})
18
- # In a real implementation, this would render:
19
- # - Health
20
- # - Armor
21
- # - Ammo
22
- # - Weapons
23
- # - Face
24
- # - Keys
25
- # - etc.
26
-
27
- # For now, we'll just render some placeholder text
28
- health = player_data[:health] || 100
29
- armor = player_data[:armor] || 0
30
- ammo = player_data[:ammo] || 50
31
- weapon = player_data[:weapon] || "Pistol"
32
-
33
- # Draw the HUD background
34
- draw_background
35
-
36
- # Draw the HUD elements
37
- draw_health(health)
38
- draw_armor(armor)
39
- draw_ammo(ammo)
40
- draw_weapon(weapon)
41
- end
42
-
43
- private
44
-
45
- # Draw the HUD background
46
- def draw_background
47
- color = Gosu::Color.new(128, 0, 0, 0) # Semi-transparent black
48
- @window.draw_quad(
49
- 0, @window.height - 80, color,
50
- @window.width, @window.height - 80, color,
51
- @window.width, @window.height, color,
52
- 0, @window.height, color
53
- )
54
- end
55
-
56
- # Draw the health display
57
- # @param health [Integer] the player's health
58
- def draw_health(health)
59
- @font.draw_text("Health: #{health}", 20, @window.height - 70, 0, 1, 1, Gosu::Color::RED)
60
- end
61
-
62
- # Draw the armor display
63
- # @param armor [Integer] the player's armor
64
- def draw_armor(armor)
65
- @font.draw_text("Armor: #{armor}", 20, @window.height - 50, 0, 1, 1, Gosu::Color::GREEN)
66
- end
67
-
68
- # Draw the ammo display
69
- # @param ammo [Integer] the player's ammo
70
- def draw_ammo(ammo)
71
- @font.draw_text("Ammo: #{ammo}", @window.width - 120, @window.height - 70, 0, 1, 1, Gosu::Color::YELLOW)
72
- end
73
-
74
- # Draw the weapon display
75
- # @param weapon [String] the player's current weapon
76
- def draw_weapon(weapon)
77
- @font.draw_text("Weapon: #{weapon}", @window.width - 120, @window.height - 50, 0, 1, 1, Gosu::Color::WHITE)
78
- end
79
- end
80
- end