iNES 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []