gbtiles 0.1.1 → 0.2.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +22 -35
  3. data/bin/gbt +24 -0
  4. data/lib/gbtiles/gbm/cli/convert.rb +9 -1
  5. data/lib/gbtiles/gbm/export/asm/asm.h.erb +1 -1
  6. data/lib/gbtiles/gbm/export/asm/asm.rb +3 -0
  7. data/lib/gbtiles/gbm/export/asm/asm.s.erb +1 -1
  8. data/lib/gbtiles/gbm/import/gbm_file.rb +1 -1
  9. data/lib/gbtiles/gbm/map/objects/map_tile_data.rb +1 -3
  10. data/lib/gbtiles/gbr/cli/convert.rb +9 -1
  11. data/lib/gbtiles/gbr/export/asm/asm.h.erb +1 -1
  12. data/lib/gbtiles/gbr/export/asm/asm.rb +3 -0
  13. data/lib/gbtiles/gbr/export/asm/asm.s.erb +1 -1
  14. data/lib/gbtiles/gbr/import/gbr_file.rb +1 -1
  15. data/lib/gbtiles/gbr/tile_set/objects/tile_data.rb +1 -1
  16. data/lib/gbtiles/gbt/cli/convert.rb +58 -0
  17. data/lib/gbtiles/gbt/export/asm/asm.h.erb +11 -0
  18. data/lib/gbtiles/gbt/export/asm/asm.rb +63 -0
  19. data/lib/gbtiles/gbt/export/asm/asm.s.erb +20 -0
  20. data/lib/gbtiles/gbt/export/asm/channel.rb +156 -0
  21. data/lib/gbtiles/gbt/export/asm/channels/noise.rb +84 -0
  22. data/lib/gbtiles/gbt/export/asm/channels/pulse.rb +88 -0
  23. data/lib/gbtiles/gbt/export/asm/channels/wav.rb +105 -0
  24. data/lib/gbtiles/gbt/export/asm/converter.rb +37 -0
  25. data/lib/gbtiles/gbt/export/asm/effects/arpeggio.rb +16 -0
  26. data/lib/gbtiles/gbt/export/asm/effects/break_and_set_step.rb +16 -0
  27. data/lib/gbtiles/gbt/export/asm/effects/cut_note.rb +16 -0
  28. data/lib/gbtiles/gbt/export/asm/effects/jump.rb +16 -0
  29. data/lib/gbtiles/gbt/export/asm/effects/pan.rb +19 -0
  30. data/lib/gbtiles/gbt/export/asm/effects/speed.rb +22 -0
  31. data/lib/gbtiles/gbt/export/asm/effects/volume.rb +13 -0
  32. data/lib/gbtiles/gbt/import/mod_file.rb +65 -0
  33. data/lib/gbtiles/gbt/mod_data/mod_data.rb +21 -0
  34. data/lib/gbtiles/gbt/mod_data/pattern.rb +16 -0
  35. data/lib/gbtiles/gbt/mod_data/sample.rb +16 -0
  36. data/lib/gbtiles/helpers/data_type.rb +11 -0
  37. data/lib/gbtiles/version.rb +1 -1
  38. metadata +32 -38
@@ -0,0 +1,156 @@
1
+ require "gbtiles/gbt/export/asm/effects/arpeggio"
2
+ require "gbtiles/gbt/export/asm/effects/break_and_set_step"
3
+ require "gbtiles/gbt/export/asm/effects/cut_note"
4
+ require "gbtiles/gbt/export/asm/effects/jump"
5
+ require "gbtiles/gbt/export/asm/effects/pan"
6
+ require "gbtiles/gbt/export/asm/effects/speed"
7
+ require "gbtiles/gbt/export/asm/effects/volume"
8
+
9
+ module GBTiles
10
+ module GBT
11
+ module Export
12
+ module ASM
13
+ class Channel
14
+ include GBTiles::GBT::Export::ASM::Effects
15
+
16
+ NOTES = [
17
+ 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016, 960, 907,
18
+ 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453,
19
+ 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226,
20
+ 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113,
21
+ 107, 101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56,
22
+ 53, 50, 47, 45, 42, 40, 37, 35, 33, 31, 30, 28
23
+ ];
24
+
25
+ attr_accessor :channel_number
26
+
27
+ @data = [ 0, 0, 0, 0 ]
28
+
29
+ def data
30
+ @data
31
+ end
32
+
33
+ def data=(value)
34
+ if value.kind_of?(Array) then
35
+ @data = value
36
+ else
37
+ @data = value.unpack('CCCC')
38
+ end
39
+ end
40
+
41
+ def initialize channel_number
42
+ @channel_number = channel_number
43
+ end
44
+
45
+ # Channel information
46
+
47
+ def is_pulse?
48
+ false
49
+ end
50
+
51
+ def is_wav?
52
+ false
53
+ end
54
+
55
+ def is_noise?
56
+ false
57
+ end
58
+
59
+ # Data
60
+
61
+ def sample_number
62
+ (@data[0] & 0xF0) | ((@data[2] & 0xF0) >> 4)
63
+ end
64
+
65
+ def sample_period
66
+ @data[1] | ((@data[0] & 0xF) << 8)
67
+ end
68
+
69
+ def is_empty_effect?
70
+ effect_number == 0 && effect_param == 0
71
+ end
72
+
73
+ def effect_number
74
+ @data[2] & 0xF
75
+ end
76
+
77
+ def effect_param
78
+ @data[3]
79
+ end
80
+
81
+ def effect_param_1
82
+ (@data[3] & 0xF0) >> 4
83
+ end
84
+
85
+ def effect_param_2
86
+ @data[3] & 0x0F
87
+ end
88
+
89
+ def effect_param_as_bcd
90
+ (((effect_param & 0xF0) >> 4) * 10) + (effect_param & 0xF)
91
+ end
92
+
93
+ def convert_volume
94
+ (effect_param == 64) ? 0xF : (effect_param >> 2);
95
+ end
96
+
97
+ # Amiga's 50 Hz to GB's 60 Hz
98
+ def convert_speed speed
99
+ speed * 60 / 50
100
+ end
101
+
102
+ def convert_effect
103
+ if effect_number == 0x0 then
104
+ return effect_arpeggio
105
+ end
106
+
107
+ if effect_number == 0xB then
108
+ return effect_jump
109
+ end
110
+
111
+ if effect_number == 0xC then
112
+ return effect_volume
113
+ end
114
+
115
+ if effect_number == 0xD then
116
+ return effect_break_and_set_step
117
+ end
118
+
119
+ if effect_number == 0xE && effect_param_1 == 0x8 then
120
+ return effect_pan
121
+ end
122
+
123
+ if effect_number == 0xE && effect_param_1 == 0xC then
124
+ return effect_cut_note
125
+ end
126
+
127
+ if effect_number == 0xF then
128
+ return effect_speed
129
+ end
130
+
131
+ throw "Unsupported effect"
132
+ end
133
+
134
+ def note_index
135
+ period = sample_period
136
+
137
+ if period <= 0 then
138
+ return -1
139
+ end
140
+
141
+ if !is_noise? then
142
+ if !period.between?(NOTES.last, NOTES.first) then
143
+ throw "Note `#{period}` out of bounds"
144
+ end
145
+ end
146
+
147
+ NOTES.index(
148
+ NOTES.min_by { |x| (period - x).abs }
149
+ )
150
+ end
151
+
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,84 @@
1
+ # CHANNEL 4
2
+
3
+ require "gbtiles/gbt/export/asm/channel"
4
+
5
+ module GBTiles
6
+ module GBT
7
+ module Export
8
+ module ASM
9
+ module Channels
10
+ class Noise < GBTiles::GBT::Export::ASM::Channel
11
+
12
+ def initialize
13
+ super(4)
14
+ end
15
+
16
+ def is_noise?
17
+ true
18
+ end
19
+
20
+ def convert
21
+ if sample_period == 0 then
22
+ convert_note_not_new
23
+ else
24
+ convert_note_new
25
+ end
26
+ end
27
+
28
+ def convert_note_not_new
29
+ if is_empty_effect? then
30
+ return [0]
31
+ end
32
+
33
+ # Volume effect
34
+ if effect_number == 0xC then
35
+ return [
36
+ (1 << 5) | convert_volume
37
+ ]
38
+ end
39
+
40
+ # Other effects
41
+ begin
42
+ converted = convert_effect
43
+
44
+ return [
45
+ (1 << 6) | converted[:number],
46
+ converted[:params]
47
+ ]
48
+ rescue Exception => e
49
+ # Silence
50
+ end
51
+
52
+ return [0]
53
+ end
54
+
55
+ def convert_note_new
56
+ instrument = (sample_number - 16) & 0x1F
57
+
58
+ # Volume effect
59
+ if effect_number == 0xC then
60
+ return [
61
+ (1 << 7) | instrument,
62
+ convert_volume
63
+ ]
64
+ end
65
+
66
+ # Other effects
67
+ begin
68
+ converted = convert_effect
69
+
70
+ return [
71
+ (1 << 7) | instrument,
72
+ (1 << 7) | converted[:number],
73
+ converted[:params]
74
+ ]
75
+ rescue Exception => e
76
+ throw "Noise - Invalid command: #{e}"
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,88 @@
1
+ # CHANNEL 1
2
+ # CHANNEL 2
3
+
4
+ require "gbtiles/gbt/export/asm/channel"
5
+
6
+ module GBTiles
7
+ module GBT
8
+ module Export
9
+ module ASM
10
+ module Channels
11
+ class Pulse < GBTiles::GBT::Export::ASM::Channel
12
+
13
+ def initialize(channel_number)
14
+ super(channel_number)
15
+ end
16
+
17
+ def is_pulse?
18
+ true
19
+ end
20
+
21
+ def convert
22
+ if sample_period == 0 then
23
+ convert_note_not_new
24
+ else
25
+ convert_note_new
26
+ end
27
+ end
28
+
29
+ def convert_note_not_new
30
+ instrument = sample_number & 3
31
+
32
+ if is_empty_effect? then
33
+ return [0]
34
+ end
35
+
36
+ # Volume effect
37
+ if effect_number == 0xC then
38
+ return [
39
+ (1 << 5) | convert_volume
40
+ ]
41
+ end
42
+
43
+ # Other effects
44
+ begin
45
+ converted = convert_effect
46
+
47
+ return [
48
+ (1 << 6) | (instrument << 4) | converted[:number],
49
+ converted[:params]
50
+ ]
51
+ rescue Exception => e
52
+ # Silence
53
+ end
54
+
55
+ return [0]
56
+ end
57
+
58
+ def convert_note_new
59
+ instrument = sample_number & 3
60
+
61
+ # Volume effect
62
+ if effect_number == 0xC then
63
+ return [
64
+ (1 << 7) | note_index,
65
+ (instrument << 4) | convert_volume
66
+ ]
67
+ end
68
+
69
+ # Other effects
70
+ begin
71
+ converted = convert_effect
72
+
73
+ return [
74
+ (1 << 7) | note_index,
75
+ (1 << 7) | (instrument << 4) | converted[:number],
76
+ converted[:params]
77
+ ]
78
+ rescue Exception => e
79
+ throw "Pulse - Invalid command: #{e}"
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,105 @@
1
+ # CHANNEL 3
2
+
3
+ require "gbtiles/gbt/export/asm/channel"
4
+
5
+ module GBTiles
6
+ module GBT
7
+ module Export
8
+ module ASM
9
+ module Channels
10
+ class Wav < GBTiles::GBT::Export::ASM::Channel
11
+
12
+ def initialize
13
+ super(3)
14
+ end
15
+
16
+ def is_wav?
17
+ true
18
+ end
19
+
20
+ def convert_volume
21
+ case super
22
+ when 0..3
23
+ return 0
24
+ when 4..7
25
+ return 3
26
+ when 8..11
27
+ return 2
28
+ when 12..15
29
+ return 1
30
+ else
31
+ return 1
32
+ end
33
+ end
34
+
35
+ def convert
36
+ if sample_period == 0 then
37
+ convert_note_not_new
38
+ else
39
+ convert_note_new
40
+ end
41
+ end
42
+
43
+ def convert_note_not_new
44
+ if is_empty_effect? then
45
+ return [0]
46
+ end
47
+
48
+ # Volume effect
49
+ if effect_number == 0xC then
50
+ return [
51
+ (1 << 5) | convert_volume
52
+ ]
53
+ end
54
+
55
+ # Other effects
56
+ begin
57
+ converted = convert_effect
58
+
59
+ return [
60
+ (1 << 6) | converted[:number],
61
+ converted[:params]
62
+ ]
63
+
64
+ rescue Exception => e
65
+ # Silence
66
+ end
67
+
68
+ return [0]
69
+ end
70
+
71
+ def convert_note_new
72
+ instrument = (sample_number - 8) & 15
73
+
74
+ # Volume effect
75
+ if effect_number == 0xC then
76
+ return [
77
+ (1 << 7) | note_index,
78
+ (convert_volume << 4) | instrument
79
+ ]
80
+ end
81
+
82
+ # Other effects
83
+ begin
84
+ converted = convert_effect
85
+
86
+ if (converted[:number] > 7) then
87
+ throw "Invalid command: only 0-7 allowed in this mode"
88
+ end
89
+
90
+ return [
91
+ (1 << 7) | note_index,
92
+ (1 << 7) | (converted_num << 4) | instrument,
93
+ converted_params
94
+ ]
95
+ rescue Exception => e
96
+ throw "Wav - Invalid command: #{e}"
97
+ end
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,37 @@
1
+ require "gbtiles/gbt/export/asm/channels/pulse"
2
+ require "gbtiles/gbt/export/asm/channels/wav"
3
+ require "gbtiles/gbt/export/asm/channels/noise"
4
+
5
+ require "erb"
6
+
7
+ module GBTiles
8
+ module GBT
9
+ module Export
10
+ module ASM
11
+ class Converter
12
+
13
+ CHANNELS = {
14
+ 1 => GBTiles::GBT::Export::ASM::Channels::Pulse.new(1),
15
+ 2 => GBTiles::GBT::Export::ASM::Channels::Pulse.new(2),
16
+ 3 => GBTiles::GBT::Export::ASM::Channels::Wav.new,
17
+ 4 => GBTiles::GBT::Export::ASM::Channels::Noise.new
18
+ }
19
+
20
+ def convert data
21
+ CHANNELS[1].data = data[0..3]
22
+ CHANNELS[2].data = data[4..7]
23
+ CHANNELS[3].data = data[8..11]
24
+ CHANNELS[4].data = data[12..15]
25
+
26
+ [
27
+ CHANNELS[1].convert.map { |x| sprintf('0x%02X', x) }.join(', '),
28
+ CHANNELS[2].convert.map { |x| sprintf('0x%02X', x) }.join(', '),
29
+ CHANNELS[3].convert.map { |x| sprintf('0x%02X', x) }.join(', '),
30
+ CHANNELS[4].convert.map { |x| sprintf('0x%02X', x) }.join(', ')
31
+ ].join(', ')
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end