iNES 1.0.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.
Files changed (3) hide show
  1. data/README.md +1 -0
  2. data/lib/ines.rb +135 -0
  3. metadata +46 -0
@@ -0,0 +1 @@
1
+ # iNES ROM format for Ruby #
@@ -0,0 +1,135 @@
1
+
2
+ class INES
3
+ # Header size (16 bytes)
4
+ INES_HEADER_SIZE = 0x10
5
+
6
+ # Trainer size (512 bytes)
7
+ INES_TRAINER_SIZE = 0x200
8
+
9
+ # Program (PRG) ROM size (16384 bytes)
10
+ INES_PRG_PAGE_SIZE = 0x4000
11
+
12
+ # Character (CHR) ROM size (8192 bytes)
13
+ INES_CHR_PAGE_SIZE = 0x2000
14
+
15
+ # The ROM, stored as an array of bytes
16
+ bytes = []
17
+
18
+ # Create an INES instance with an optional file to load
19
+ def initialize(filename = nil)
20
+ unless filename.nil?
21
+ load(filename)
22
+ end
23
+ end
24
+
25
+ # Load a file, replacing all data previously loaded
26
+ def load(filename)
27
+ unless File.file? filename
28
+ raise "file not found: #{filename}"
29
+ end
30
+
31
+ file = File.new(filename, 'r')
32
+ @bytes = file.read.unpack 'C*'
33
+ file.close
34
+
35
+ return nil
36
+ end
37
+
38
+ # Save the current data to file
39
+ def save(filename, overwrite = false)
40
+ if File.file?(filename) && !overwrite
41
+ raise "file exists: #{filename}"
42
+ end
43
+
44
+ file = File.new(filename, 'wb')
45
+ file.write @bytes.pack('C*')
46
+ file.close
47
+
48
+ return nil
49
+ end
50
+
51
+ # Write data to the ROM at the defined offset
52
+ def write(offset, data, enlarge = false)
53
+ if (offset + data.length) > @bytes.length && !enlarge
54
+ raise 'writing past the end of the rom'
55
+ end
56
+
57
+ data.length.times { @bytes.delete_at offset }
58
+
59
+ for i in 0 ... data.length
60
+ @bytes.insert(offset + i, data[i])
61
+ end
62
+
63
+ return nil
64
+ end
65
+
66
+ # Calculate the data offset, excluding header and trainer (if applicable)
67
+ def offset
68
+ return INES_HEADER_SIZE + ((self.trainer?) ? INES_TRAINER_SIZE : 0)
69
+ end
70
+
71
+ # Get the iNES header as an array of bytes
72
+ def header
73
+ if @bytes.length < INES_HEADER_SIZE
74
+ raise 'invalid or missing header'
75
+ end
76
+
77
+ return @bytes.slice(0, INES_HEADER_SIZE)
78
+ end
79
+
80
+ # Check whether the ROM has a trainer
81
+ def trainer?
82
+ return ((self.header[6] & 0xF) & 4) > 0
83
+ end
84
+
85
+ # Retrieve the trainer from the ROM, if one is available
86
+ def trainer
87
+ if self.trainer?
88
+ if (self.offset + INES_TRAINER_SIZE) > @bytes.length
89
+ raise 'invalid trainer'
90
+ end
91
+
92
+ return @bytes.slice(self.offset, INES_TRAINER_SIZE)
93
+ end
94
+
95
+ return nil
96
+ end
97
+
98
+ # Calculate the program data (PRG) offset from the start of the file
99
+ def prg_offset
100
+ return self.offset
101
+ end
102
+
103
+ # Calculate the size of the program data (PRG)
104
+ def prg_size
105
+ return self.header[4] * INES_PRG_PAGE_SIZE
106
+ end
107
+
108
+ # Retrieve the program data (PRG) from the ROM
109
+ def prg
110
+ if (self.prg_offset + self.prg_size) > @bytes.length
111
+ raise 'invalid prg'
112
+ end
113
+
114
+ return @bytes.slice(self.prg_offset, self.prg_size)
115
+ end
116
+
117
+ # Calculate the character (CHR) offset from the start of the file
118
+ def chr_offset
119
+ return self.offset + self.prg_size
120
+ end
121
+
122
+ # Calculate the size of the character data (CHR)
123
+ def chr_size
124
+ return self.header[5] * INES_CHR_PAGE_SIZE
125
+ end
126
+
127
+ # Retrieve the character data (CHR) from the ROM
128
+ def chr
129
+ if (self.chr_offset + self.chr_size) > @bytes.length
130
+ raise 'invalid chr'
131
+ end
132
+
133
+ return @bytes.slice(self.chr_offset, self.chr_size)
134
+ end
135
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iNES
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jack Wilsdon
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-22 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Manipulate iNES ROM files and extract trainer, PRG and CHR roms!
15
+ email: jack.wilsdon@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/ines.rb
21
+ - README.md
22
+ homepage: http://github.com/jackwilsdon/ines
23
+ licenses: []
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 1.8.11
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: iNES ROM format for Ruby
46
+ test_files: []