snes_utils 0.2.0 → 0.3.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/bin/png2snes +12 -1
- data/bin/vas +2 -1
- data/lib/mini_assembler/superfx/definitions.rb +158 -0
- data/lib/png2snes/png2snes.rb +51 -20
- data/lib/snes_utils.rb +1 -2
- data/lib/vas/vas.rb +230 -28
- data/spec/mini_assembler_spec.rb +136 -0
- data/spec/spc700_spec.rb +322 -0
- data/spec/spec_helper.rb +100 -0
- data/spec/vas_spec.rb +5 -0
- data/spec/wdc65816_spec.rb +322 -0
- metadata +18 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9bce5ff7aea0b674c5c19db5c83979f66b4993e9b0de36a19c432cc7bcb09745
|
4
|
+
data.tar.gz: 78b040ccc9a686496535c135e3908ab63bfcd9c2c4fece2761a77f5588f49a9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfd37be40699f3a075c5b5c1e1779bb8fe4aed85da84d1f64be3a325d427416c070df8677d3f054d63edc63339080c467211feb903006878726fc8d66c84fee8
|
7
|
+
data.tar.gz: 44d97b051f1b75b94e3f823ec41efdbd08100a24674fb0255e3e40130bf2418506b6bd31035813ae31ff0253c2874155ed5fa40caf10806bd21ff4f745f32e4d
|
data/bin/png2snes
CHANGED
@@ -8,6 +8,8 @@ OptionParser.new do |opts|
|
|
8
8
|
opts.on('-f', '--file FILENAME', 'PNG source file') { |o| options[:filename] = o }
|
9
9
|
opts.on('-b', '--bpp BPP', 'BPP') { |o| options[:bpp] = o }
|
10
10
|
opts.on('-a', '--alpha ALPHA', 'ALPHA') { |o| options[:alpha] = o }
|
11
|
+
opts.on('-m', '--mode7', 'mode 7') { |o| options[:mode7] = o }
|
12
|
+
opts.on('-o', '--offset OFFSET', 'mode 7 palette offset') { |o| options[:m7_palette_offset] = o }
|
11
13
|
end.parse!
|
12
14
|
|
13
15
|
raise OptionParser::MissingArgument, 'Must specify PNG source file' if options[:filename].nil?
|
@@ -18,6 +20,15 @@ else
|
|
18
20
|
alpha = nil
|
19
21
|
end
|
20
22
|
|
21
|
-
|
23
|
+
if options[:m7_palette_offset]
|
24
|
+
m7_palette_offset = options[:m7_palette_offset].to_i
|
25
|
+
else
|
26
|
+
m7_palette_offset = nil
|
27
|
+
end
|
28
|
+
|
29
|
+
c = SnesUtils::Png2Snes.new(options[:filename], bpp: options[:bpp].to_i,
|
30
|
+
alpha: alpha,
|
31
|
+
mode7: options[:mode7],
|
32
|
+
m7_palette_offset: m7_palette_offset)
|
22
33
|
c.write_palette
|
23
34
|
c.write_image
|
data/bin/vas
CHANGED
@@ -11,6 +11,7 @@ OptionParser.new do |opts|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
opts.on('-f', '--file FILENAME', 'ASM file') { |o| options[:filename] = o }
|
14
|
+
opts.on("-o", "--out FILENAME", "output file") { |o| options[:outfile] = o }
|
14
15
|
end.parse!
|
15
16
|
|
16
|
-
SnesUtils::Vas.new(options[:filename]).assemble
|
17
|
+
SnesUtils::Vas.new(options[:filename], options[:outfile]).assemble
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SnesUtils
|
4
|
+
module Superfx
|
5
|
+
class Definitions
|
6
|
+
HEX_DIGIT = '[0-9a-f]'
|
7
|
+
REG = "[rR](\\d{1,2})"
|
8
|
+
LNK = "([1-4])"
|
9
|
+
HEX = "\\$?(#{HEX_DIGIT})"
|
10
|
+
HEX8 = "\\$?(#{HEX_DIGIT}{1,2})"
|
11
|
+
HEX16 = "\\$?(#{HEX_DIGIT}{1,4})"
|
12
|
+
|
13
|
+
SINGLE_OPERAND_INSTRUCTIONS = %i[imp imm4 rn rm rel lnk].freeze
|
14
|
+
DOUBLE_OPERAND_INSTRUCTIONS = %i[rn_rn rn_imm8 rn_imm16 rn_addr rn_addrl addr_rn addrl_rn].freeze
|
15
|
+
REL_INSTRUCTIONS = %i[rel].freeze
|
16
|
+
BIT_INSTRUCTIONS = %i[].freeze
|
17
|
+
SFX_INSTRUCTIONS = %i[imm4 rn rm rn_rn rn_imm8 rn_imm16 rn_addr rn_addrl addr_rn addrl_rn].freeze
|
18
|
+
MOV_INSTRUCTIONS = %i[rn_rn]
|
19
|
+
SHORT_ADDR_INSTRUCTIONS = %i[rn_addr addr_rn]
|
20
|
+
INV_DEST_INSTRUCTIONS = %i[addr_rn addrl_rn]
|
21
|
+
|
22
|
+
MODES_REGEXES = {
|
23
|
+
imp: /^$/, # nothing
|
24
|
+
imm4: /^##{HEX}$/, # #0-f
|
25
|
+
lnk: /^##{LNK}$/, # #1-4
|
26
|
+
rn: /^#{REG}$/, # R1
|
27
|
+
rm: /^\(#{REG}\)$/, # (R1)
|
28
|
+
rel: /^#{HEX16}$/i, # label / 1234
|
29
|
+
rn_rn: /^#{REG},#{REG}$/, # R1, R2
|
30
|
+
rn_imm8: /^#{REG},##{HEX8}$/, # R1, #12
|
31
|
+
rn_imm16: /^#{REG},##{HEX16}$/, # R1, #1234
|
32
|
+
rn_addr: /^#{REG},\(#{HEX16}\)$/, # R1, (1234) ; -> actual data is 1234 / 2
|
33
|
+
rn_addrl: /^#{REG},\(#{HEX16}\)$/, # R1, (1234) ; label
|
34
|
+
addr_rn: /^\(#{HEX16}\),#{REG}$/, # (1234), R1 ; -> actual data is 1234 / 2
|
35
|
+
addrl_rn: /^\(#{HEX16}\),#{REG}$/, # (1234), R1 ; label
|
36
|
+
}.freeze
|
37
|
+
|
38
|
+
OPCODES_DATA = [
|
39
|
+
# From game pak ROM to register
|
40
|
+
{ opcode: 0xef, mnemonic: 'GETB', mode: :imp, length: 1, alt: nil },
|
41
|
+
{ opcode: 0xef, mnemonic: 'GETBH', mode: :imp, length: 2, alt: 0x3d },
|
42
|
+
{ opcode: 0xef, mnemonic: 'GETBL', mode: :imp, length: 2, alt: 0x3e },
|
43
|
+
{ opcode: 0xef, mnemonic: 'GETBS', mode: :imp, length: 2, alt: 0x3f },
|
44
|
+
{ opcode: 0xdf, mnemonic: 'GETC', mode: :imp, length: 1, alt: nil },
|
45
|
+
|
46
|
+
# From game pak RAM to register
|
47
|
+
{ opcode: 0x4, mnemonic: 'LDW', mode: :rm, length: 1, alt: nil },
|
48
|
+
{ opcode: 0x4, mnemonic: 'LDB', mode: :rm, length: 1, alt: 0x3d },
|
49
|
+
{ opcode: 0xf, mnemonic: 'LM', mode: :rn_addrl, length: 4, alt: 0x3d },
|
50
|
+
{ opcode: 0xa, mnemonic: 'LMS', mode: :rn_addr, length: 3, alt: 0x3d },
|
51
|
+
|
52
|
+
# From register to game pak RAM
|
53
|
+
{ opcode: 0x3, mnemonic: 'STW', mode: :rm, length: 1, alt: nil },
|
54
|
+
{ opcode: 0x3, mnemonic: 'STB', mode: :rm, length: 2, alt: 0x3d },
|
55
|
+
{ opcode: 0xf, mnemonic: 'SM', mode: :addrl_rn, length: 4, alt: 0x3e },
|
56
|
+
{ opcode: 0xa, mnemonic: 'SMS', mode: :addr_rn, length: 3, alt: 0x3e },
|
57
|
+
{ opcode: 0x90, mnemonic: 'SBK', mode: :imp, length: 1, alt: nil },
|
58
|
+
|
59
|
+
# From register to register
|
60
|
+
{ opcode: 0x2010, mnemonic: 'MOVE', mode: :rn_rn, length: 2, alt: nil },
|
61
|
+
{ opcode: 0x20b0, mnemonic: 'MOVES', mode: :rn_rn, length: 2, alt: nil },
|
62
|
+
|
63
|
+
# Immediate data to register
|
64
|
+
{ opcode: 0xf, mnemonic: 'IWT', mode: :rn_imm16, length: 3, alt: nil },
|
65
|
+
{ opcode: 0xa, mnemonic: 'IBT', mode: :rn_imm8, length: 2, alt: nil },
|
66
|
+
|
67
|
+
# Arithmetic operations
|
68
|
+
{ opcode: 0x5, mnemonic: 'ADD', mode: :rn, length: 1, alt: nil },
|
69
|
+
{ opcode: 0x5, mnemonic: 'ADD', mode: :imm4, length: 2, alt: 0x3e },
|
70
|
+
{ opcode: 0x5, mnemonic: 'ADC', mode: :rn, length: 2, alt: 0x3d },
|
71
|
+
{ opcode: 0x5, mnemonic: 'ADC', mode: :imm4, length: 2, alt: 0x3f },
|
72
|
+
|
73
|
+
{ opcode: 0x6, mnemonic: 'SUB', mode: :rn, length: 1, alt: nil },
|
74
|
+
{ opcode: 0x6, mnemonic: 'SUB', mode: :imm4, length: 2, alt: 0x3e },
|
75
|
+
{ opcode: 0x6, mnemonic: 'SBC', mode: :rn, length: 2, alt: 0x3d },
|
76
|
+
|
77
|
+
{ opcode: 0x6, mnemonic: 'CMP', mode: :rn, length: 2, alt: 0x3f },
|
78
|
+
|
79
|
+
{ opcode: 0x8, mnemonic: 'MULT', mode: :rn, length: 1, alt: nil },
|
80
|
+
{ opcode: 0x8, mnemonic: 'MULT', mode: :imm4, length: 2, alt: 0x3e },
|
81
|
+
{ opcode: 0x8, mnemonic: 'UMULT', mode: :rn, length: 2, alt: 0x3d },
|
82
|
+
{ opcode: 0x8, mnemonic: 'UMULT', mode: :imm4, length: 2, alt: 0x3f },
|
83
|
+
{ opcode: 0x9f, mnemonic: 'FMULT', mode: :imp, length: 1, alt: nil },
|
84
|
+
{ opcode: 0x9f, mnemonic: 'LMULT', mode: :imp, length: 2, alt: 0x3d },
|
85
|
+
|
86
|
+
{ opcode: 0x96, mnemonic: 'DIV2', mode: :imp, length: 2, alt: 0x3d },
|
87
|
+
|
88
|
+
{ opcode: 0xd, mnemonic: 'INC', mode: :rn, length: 1, alt: nil },
|
89
|
+
{ opcode: 0xe, mnemonic: 'DEC', mode: :rn, length: 1, alt: nil },
|
90
|
+
|
91
|
+
# Logical operations
|
92
|
+
{ opcode: 0x7, mnemonic: 'AND', mode: :rn, length: 1, alt: nil },
|
93
|
+
{ opcode: 0x7, mnemonic: 'AND', mode: :imm4, length: 2, alt: 0x3e },
|
94
|
+
{ opcode: 0xc, mnemonic: 'OR', mode: :rn, length: 1, alt: nil },
|
95
|
+
{ opcode: 0xc, mnemonic: 'OR', mode: :imm4, length: 2, alt: 0x3e },
|
96
|
+
{ opcode: 0x4f, mnemonic: 'NOT', mode: :imp, length: 1, alt: nil },
|
97
|
+
{ opcode: 0xc, mnemonic: 'XOR', mode: :rn, length: 2, alt: 0x3d },
|
98
|
+
{ opcode: 0xc, mnemonic: 'XOR', mode: :imm4, length: 2, alt: 0x3f },
|
99
|
+
{ opcode: 0x7, mnemonic: 'BIC', mode: :rn, length: 2, alt: 0x3d },
|
100
|
+
{ opcode: 0x7, mnemonic: 'BIC', mode: :imm4, length: 2, alt: 0x3f },
|
101
|
+
|
102
|
+
# Shift
|
103
|
+
{ opcode: 0x96, mnemonic: 'ASR', mode: :imp, length: 1, alt: nil },
|
104
|
+
{ opcode: 0x03, mnemonic: 'LSR', mode: :imp, length: 1, alt: nil },
|
105
|
+
{ opcode: 0x04, mnemonic: 'ROL', mode: :imp, length: 1, alt: nil },
|
106
|
+
{ opcode: 0x97, mnemonic: 'ROR', mode: :imp, length: 1, alt: nil },
|
107
|
+
|
108
|
+
# Byte transfer
|
109
|
+
{ opcode: 0xc0, mnemonic: 'HIB', mode: :imp, length: 1, alt: nil },
|
110
|
+
{ opcode: 0x9e, mnemonic: 'LOB', mode: :imp, length: 1, alt: nil },
|
111
|
+
{ opcode: 0x70, mnemonic: 'MERGE', mode: :imp, length: 1, alt: nil },
|
112
|
+
{ opcode: 0x95, mnemonic: 'SEX', mode: :imp, length: 1, alt: nil },
|
113
|
+
{ opcode: 0x4d, mnemonic: 'SWAP', mode: :imp, length: 1, alt: nil },
|
114
|
+
|
115
|
+
# Jump, branch and loop
|
116
|
+
{ opcode: 0x9, mnemonic: 'JMP', mode: :rn, length: 1, alt: nil },
|
117
|
+
{ opcode: 0x9, mnemonic: 'LJMP', mode: :rn, length: 2, alt: 0x3d },
|
118
|
+
{ opcode: 0x05, mnemonic: 'BRA', mode: :rel, length: 2, alt: nil },
|
119
|
+
{ opcode: 0x06, mnemonic: 'BGE', mode: :rel, length: 2, alt: nil },
|
120
|
+
{ opcode: 0x07, mnemonic: 'BLT', mode: :rel, length: 2, alt: nil },
|
121
|
+
{ opcode: 0x08, mnemonic: 'BNE', mode: :rel, length: 2, alt: nil },
|
122
|
+
{ opcode: 0x09, mnemonic: 'BEQ', mode: :rel, length: 2, alt: nil },
|
123
|
+
{ opcode: 0x0a, mnemonic: 'BPL', mode: :rel, length: 2, alt: nil },
|
124
|
+
{ opcode: 0x0b, mnemonic: 'BMI', mode: :rel, length: 2, alt: nil },
|
125
|
+
{ opcode: 0x0c, mnemonic: 'BCC', mode: :rel, length: 2, alt: nil },
|
126
|
+
{ opcode: 0x0d, mnemonic: 'BCS', mode: :rel, length: 2, alt: nil },
|
127
|
+
{ opcode: 0x0e, mnemonic: 'BVC', mode: :rel, length: 2, alt: nil },
|
128
|
+
{ opcode: 0x0f, mnemonic: 'BVS', mode: :rel, length: 2, alt: nil },
|
129
|
+
{ opcode: 0x3c, mnemonic: 'LOOP', mode: :imp, length: 1, alt: nil },
|
130
|
+
{ opcode: 0x9, mnemonic: 'LINK', mode: :imm4, length: 1, alt: nil },
|
131
|
+
|
132
|
+
# Bank set-up
|
133
|
+
{ opcode: 0xdf, mnemonic: 'ROMB', mode: :imp, length: 2, alt: 0x3f },
|
134
|
+
{ opcode: 0xdf, mnemonic: 'RAMB', mode: :imp, length: 2, alt: 0x3e },
|
135
|
+
|
136
|
+
# Plot related
|
137
|
+
{ opcode: 0x4e, mnemonic: 'CMODE', mode: :imp, length: 2, alt: 0x3d },
|
138
|
+
{ opcode: 0x4e, mnemonic: 'COLOR', mode: :imp, length: 1, alt: nil },
|
139
|
+
{ opcode: 0x4c, mnemonic: 'PLOT', mode: :imp, length: 1, alt: nil },
|
140
|
+
{ opcode: 0x4c, mnemonic: 'RPIX', mode: :imp, length: 2, alt: 0x3d },
|
141
|
+
|
142
|
+
# Prefix flag
|
143
|
+
{ opcode: 0x3d, mnemonic: 'ALT1', mode: :imp, length: 1, alt: nil },
|
144
|
+
{ opcode: 0x3e, mnemonic: 'ALT2', mode: :imp, length: 1, alt: nil },
|
145
|
+
{ opcode: 0x3f, mnemonic: 'ALT3', mode: :imp, length: 1, alt: nil },
|
146
|
+
|
147
|
+
# Prefix register
|
148
|
+
{ opcode: 0xb, mnemonic: 'FROM', mode: :rn, length: 1, alt: nil },
|
149
|
+
{ opcode: 0x1, mnemonic: 'TO', mode: :rn, length: 1, alt: nil },
|
150
|
+
{ opcode: 0x2, mnemonic: 'WITH', mode: :rn, length: 1, alt: nil },
|
151
|
+
|
152
|
+
# GSU Control
|
153
|
+
{ opcode: 0x02, mnemonic: 'CACHE', mode: :imp, length: 1, alt: nil },
|
154
|
+
{ opcode: 0x01, mnemonic: 'NOP', mode: :imp, length: 1, alt: nil },
|
155
|
+
{ opcode: 0x00, mnemonic: 'STOP', mode: :imp, length: 1, alt: nil }].freeze
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/png2snes/png2snes.rb
CHANGED
@@ -1,22 +1,34 @@
|
|
1
1
|
module SnesUtils
|
2
2
|
class Png2Snes
|
3
|
-
|
3
|
+
CHAR_SIZE = 8
|
4
|
+
|
5
|
+
def initialize(file_path, bpp:4, alpha:nil, mode7: false, m7_palette_offset: nil)
|
4
6
|
@file_path = file_path
|
5
7
|
@file_dir = File.dirname(@file_path)
|
6
8
|
@file_name = File.basename(@file_path, File.extname(@file_path))
|
7
9
|
@image = ChunkyPNG::Image.from_file(@file_path)
|
8
|
-
@pixels = pixels_to_bgr5
|
9
10
|
|
11
|
+
@mode7 = mode7
|
12
|
+
|
13
|
+
raise ArgumentError, 'Image width and height must be a multiple of sprite size' if (@image.width % CHAR_SIZE != 0) or (@image.height % CHAR_SIZE != 0)
|
14
|
+
|
15
|
+
@pixels = pixels_to_bgr5
|
10
16
|
@palette = @pixels.uniq
|
11
|
-
@char_size = 8
|
12
17
|
|
13
|
-
|
14
|
-
|
18
|
+
if @mode7
|
19
|
+
raise ArgumentError, 'mode 7 palette offset must be multiple of 16' if m7_palette_offset % 16 != 0
|
20
|
+
raise ArgumentError, 'mode 7 palette offset must be less than 112' if m7_palette_offset > 112
|
21
|
+
@m7_palette_offset = m7_palette_offset
|
15
22
|
|
16
|
-
|
23
|
+
unshift_alpha(alpha) if alpha
|
24
|
+
fill_palette
|
25
|
+
else
|
26
|
+
raise ArgumentError, 'BPP must be 2, 4, or 8' unless [2, 4, 8].include? bpp
|
27
|
+
@bpp = bpp
|
17
28
|
|
18
|
-
|
19
|
-
|
29
|
+
unshift_alpha(alpha) if alpha
|
30
|
+
fill_palette
|
31
|
+
end
|
20
32
|
end
|
21
33
|
|
22
34
|
def pixels_to_bgr5
|
@@ -34,13 +46,17 @@ module SnesUtils
|
|
34
46
|
end
|
35
47
|
|
36
48
|
def fill_palette
|
37
|
-
target_size = 2**@bpp
|
49
|
+
target_size = @mode7 ? mode_7_pal_size : 2**@bpp
|
38
50
|
missing_colors = target_size - @palette.count
|
39
51
|
raise ArgumentError, "Palette size too large for target BPP (#{@palette.count})" if missing_colors < 0
|
40
52
|
|
41
53
|
@palette += [0] * missing_colors
|
42
54
|
end
|
43
55
|
|
56
|
+
def mode_7_pal_size
|
57
|
+
128 - @m7_palette_offset
|
58
|
+
end
|
59
|
+
|
44
60
|
def write hex, file_path
|
45
61
|
File.open(file_path, 'w+b') do |file|
|
46
62
|
file.write([hex.join].pack('H*'))
|
@@ -49,7 +65,7 @@ module SnesUtils
|
|
49
65
|
|
50
66
|
def write_palette
|
51
67
|
palette_hex = @palette.map { |c| ('%04x' % c).scan(/.{2}/).reverse.join }
|
52
|
-
write palette_hex, File.expand_path("#{@file_name}
|
68
|
+
write palette_hex, File.expand_path("#{@file_name}.pal", @file_dir)
|
53
69
|
end
|
54
70
|
|
55
71
|
def pixel_indices
|
@@ -61,16 +77,20 @@ module SnesUtils
|
|
61
77
|
def extract_sprites
|
62
78
|
pixel_idx = pixel_indices
|
63
79
|
|
64
|
-
sprite_per_row = @image.width /
|
65
|
-
sprite_per_col = @image.height /
|
80
|
+
sprite_per_row = @image.width / CHAR_SIZE
|
81
|
+
sprite_per_col = @image.height / CHAR_SIZE
|
66
82
|
sprite_per_sheet = sprite_per_row * sprite_per_col
|
67
83
|
|
68
84
|
sprites = []
|
69
85
|
(0..sprite_per_sheet-1).each do |s|
|
70
86
|
sprite = []
|
71
|
-
(0
|
72
|
-
offset = (s/sprite_per_row)*sprite_per_row *
|
73
|
-
|
87
|
+
(0..CHAR_SIZE-1).each do |r|
|
88
|
+
offset = (s/sprite_per_row)*sprite_per_row * CHAR_SIZE**2 + s % sprite_per_row * CHAR_SIZE
|
89
|
+
if @mode7
|
90
|
+
sprite += @pixels[offset + r*sprite_per_row*CHAR_SIZE, CHAR_SIZE]
|
91
|
+
else
|
92
|
+
sprite += pixel_idx[offset + r*sprite_per_row*CHAR_SIZE, CHAR_SIZE]
|
93
|
+
end
|
74
94
|
end
|
75
95
|
sprites.push(sprite)
|
76
96
|
end
|
@@ -88,7 +108,11 @@ module SnesUtils
|
|
88
108
|
end
|
89
109
|
|
90
110
|
def write_image
|
91
|
-
|
111
|
+
@mode7 ? write_image_m7 : write_image_m06
|
112
|
+
end
|
113
|
+
|
114
|
+
def write_image_m06
|
115
|
+
sprite_per_row = @image.width / CHAR_SIZE
|
92
116
|
sprites = extract_sprites
|
93
117
|
sprites_bitplanes = sprites.map { |s| extract_bitplanes s }
|
94
118
|
|
@@ -98,9 +122,9 @@ module SnesUtils
|
|
98
122
|
|
99
123
|
bitplane_bits = ""
|
100
124
|
sprite_bitplane_pairs.each do |bitplane|
|
101
|
-
(0
|
102
|
-
offset = r
|
103
|
-
bitplane_bits += bitplane[0][offset,
|
125
|
+
(0..CHAR_SIZE-1).each do |r|
|
126
|
+
offset = r*CHAR_SIZE
|
127
|
+
bitplane_bits += bitplane[0][offset, CHAR_SIZE].join + bitplane[1][offset, CHAR_SIZE].join
|
104
128
|
end
|
105
129
|
end
|
106
130
|
image_bits += bitplane_bits
|
@@ -108,8 +132,15 @@ module SnesUtils
|
|
108
132
|
end
|
109
133
|
|
110
134
|
image_hex = image_bits.scan(/.{8}/).map { |b| "%02x" % b.to_i(2) }
|
111
|
-
write image_hex, File.expand_path("#{@file_name}.
|
135
|
+
write image_hex, File.expand_path("#{@file_name}.tiles", @file_dir)
|
112
136
|
end
|
113
137
|
|
138
|
+
def write_image_m7
|
139
|
+
sprites = extract_sprites
|
140
|
+
|
141
|
+
indices = sprites.flatten.map { |color| "%02x" % (@palette.index(color) + @m7_palette_offset) }
|
142
|
+
|
143
|
+
write indices, File.expand_path("#{@file_name}.tiles", @file_dir)
|
144
|
+
end
|
114
145
|
end
|
115
146
|
end
|
data/lib/snes_utils.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'readline'
|
2
2
|
require 'chunky_png'
|
3
|
-
require 'matrix'
|
4
3
|
require 'csv'
|
5
|
-
require 'byebug'
|
6
4
|
|
7
5
|
require 'mini_assembler/mini_assembler'
|
8
6
|
require 'mini_assembler/definitions'
|
9
7
|
require 'mini_assembler/wdc65816/definitions'
|
10
8
|
require 'mini_assembler/spc700/definitions'
|
9
|
+
require 'mini_assembler/superfx/definitions'
|
11
10
|
require 'png2snes/png2snes'
|
12
11
|
require 'tmx2snes/tmx2snes'
|
13
12
|
|