badline 0.11.1 → 0.12.1
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/CHANGELOG.md +26 -0
- data/CLAUDE.md +8 -7
- data/CONTRIBUTING.md +7 -6
- data/README.md +12 -5
- data/doc/media.md +28 -1
- data/doc/pinned-behaviour.md +31 -1
- data/exe/badline-ruby +1 -1
- data/lib/badline/address_bus/saved_state.rb +4 -10
- data/lib/badline/address_bus.rb +8 -27
- data/lib/badline/audio/bare_player.rb +1 -1
- data/lib/badline/c128/bus.rb +17 -52
- data/lib/badline/c128/bus_state.rb +5 -5
- data/lib/badline/c128/drives.rb +35 -22
- data/lib/badline/c128/fast_serial.rb +1 -0
- data/lib/badline/c128/io_pages.rb +35 -0
- data/lib/badline/c128/mmu.rb +9 -7
- data/lib/badline/c128/modes.rb +17 -4
- data/lib/badline/c128/saved_state.rb +22 -0
- data/lib/badline/c128/z80.rb +49 -0
- data/lib/badline/c128/z80_pages.rb +118 -0
- data/lib/badline/c128/z80_turns.rb +106 -0
- data/lib/badline/c128.rb +21 -83
- data/lib/badline/cartridge/action_replay.rb +2 -2
- data/lib/badline/cartridge/comal80.rb +1 -7
- data/lib/badline/cartridge/dinamic.rb +0 -8
- data/lib/badline/cartridge/final_cartridge3.rb +6 -6
- data/lib/badline/cartridge/fun_play.rb +0 -8
- data/lib/badline/cartridge/game_system.rb +0 -8
- data/lib/badline/cartridge/kcs_power.rb +10 -7
- data/lib/badline/cartridge/mach5.rb +2 -4
- data/lib/badline/cartridge/magic_desk.rb +0 -8
- data/lib/badline/cartridge/ocean.rb +0 -8
- data/lib/badline/cartridge/pagefox.rb +2 -2
- data/lib/badline/cartridge/retro_replay.rb +7 -6
- data/lib/badline/cartridge/rex_utility.rb +2 -6
- data/lib/badline/cartridge/rgcd.rb +2 -2
- data/lib/badline/cartridge/simons_basic.rb +0 -5
- data/lib/badline/cartridge/super_games.rb +4 -2
- data/lib/badline/cartridge/westermann.rb +2 -6
- data/lib/badline/cartridge.rb +37 -9
- data/lib/badline/cia/fast_forward.rb +21 -3
- data/lib/badline/cia.rb +8 -5
- data/lib/badline/computer/attachments.rb +14 -95
- data/lib/badline/computer/common.rb +34 -0
- data/lib/badline/computer/kernal_traps.rb +65 -5
- data/lib/badline/computer/true_drives.rb +69 -0
- data/lib/badline/computer.rb +9 -68
- data/lib/badline/core.rb +4 -2
- data/lib/badline/cpu_port.rb +112 -0
- data/lib/badline/drive/core.rb +8 -33
- data/lib/badline/drive/fast_serial.rb +73 -0
- data/lib/badline/drive/idle.rb +1 -11
- data/lib/badline/drive/orbit.rb +2 -5
- data/lib/badline/drive/sleep.rb +0 -2
- data/lib/badline/drive/vias.rb +84 -0
- data/lib/badline/drive.rb +2 -0
- data/lib/badline/drive1541/disk.rb +14 -17
- data/lib/badline/drive1541/disk_state.rb +7 -15
- data/lib/badline/drive1541.rb +1 -0
- data/lib/badline/drive1571/wd1770.rb +94 -8
- data/lib/badline/drive1571.rb +8 -58
- data/lib/badline/drive1581/bus.rb +137 -0
- data/lib/badline/drive1581/cpu.rb +11 -0
- data/lib/badline/drive1581/disk.rb +135 -0
- data/lib/badline/drive1581/disk_state.rb +87 -0
- data/lib/badline/drive1581/mechanism.rb +117 -0
- data/lib/badline/drive1581/serial_port.rb +52 -0
- data/lib/badline/drive1581/slot.rb +78 -0
- data/lib/badline/drive1581/track.rb +100 -0
- data/lib/badline/drive1581/track_bytes.rb +75 -0
- data/lib/badline/drive1581/wd1772/registers.rb +89 -0
- data/lib/badline/drive1581/wd1772/sector_writes.rb +73 -0
- data/lib/badline/drive1581/wd1772/sectors.rb +150 -0
- data/lib/badline/drive1581/wd1772/state.rb +66 -0
- data/lib/badline/drive1581/wd1772/stepping.rb +109 -0
- data/lib/badline/drive1581/wd1772/tracks.rb +125 -0
- data/lib/badline/drive1581/wd1772/turn.rb +73 -0
- data/lib/badline/drive1581/wd1772.rb +216 -0
- data/lib/badline/drive1581.rb +233 -0
- data/lib/badline/frontend/app.rb +1 -3
- data/lib/badline/frontend/audio_device.rb +67 -0
- data/lib/badline/frontend/audio_sink.rb +16 -50
- data/lib/badline/frontend/boot.rb +24 -67
- data/lib/badline/frontend/buttons.rb +7 -7
- data/lib/badline/frontend/keys.rb +33 -8
- data/lib/badline/frontend/media_slots.rb +42 -0
- data/lib/badline/frontend/{confirmation.rb → menu/confirmation.rb} +4 -4
- data/lib/badline/frontend/{file_browser.rb → menu/file_browser.rb} +18 -34
- data/lib/badline/frontend/{menu_dialogs.rb → menu/menu_dialogs.rb} +3 -7
- data/lib/badline/frontend/{menu_media.rb → menu/menu_media.rb} +26 -51
- data/lib/badline/frontend/{menu_pages.rb → menu/menu_pages.rb} +5 -8
- data/lib/badline/frontend/{name_field.rb → menu/name_field.rb} +11 -24
- data/lib/badline/frontend/{pause_menu.rb → menu/pause_menu.rb} +13 -28
- data/lib/badline/frontend/menu/theme.rb +18 -0
- data/lib/badline/frontend/{filter_view.rb → player/filter_view.rb} +4 -4
- data/lib/badline/frontend/{info_view.rb → player/info_view.rb} +3 -3
- data/lib/badline/frontend/{player_window.rb → player/player_controller.rb} +17 -25
- data/lib/badline/frontend/{player_footer.rb → player/player_footer.rb} +8 -8
- data/lib/badline/frontend/{player_header.rb → player/player_header.rb} +5 -5
- data/lib/badline/frontend/{player_screen.rb → player/player_screen.rb} +4 -5
- data/lib/badline/frontend/{scope.rb → player/scope.rb} +1 -1
- data/lib/badline/frontend/{sid_view.rb → player/sid_view.rb} +16 -20
- data/lib/badline/frontend/player/theme.rb +18 -0
- data/lib/badline/frontend/{visualizer_view.rb → player/visualizer_view.rb} +8 -8
- data/lib/badline/frontend/sound.rb +19 -38
- data/lib/badline/frontend/timeline.rb +3 -14
- data/lib/badline/frontend.rb +24 -20
- data/lib/badline/iec_bus.rb +14 -2
- data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
- data/lib/badline/kernal_trap/load.rb +1 -1
- data/lib/badline/kernal_trap/save.rb +1 -1
- data/lib/badline/kernal_trap.rb +1 -1
- data/lib/badline/machine/clocking.rb +50 -0
- data/lib/badline/machine.rb +63 -6
- data/lib/badline/media/boot_disk.rb +50 -0
- data/lib/badline/media/disk_list.rb +3 -3
- data/lib/badline/media/disk_set.rb +1 -1
- data/lib/badline/media/extensions.rb +33 -0
- data/lib/badline/media/not_disk.rb +8 -0
- data/lib/badline/media/program.rb +28 -0
- data/lib/badline/media/true_drive.rb +38 -17
- data/lib/badline/media/tune.rb +35 -0
- data/lib/badline/media/vic20_cartridge.rb +1 -7
- data/lib/badline/media/vic20_media.rb +38 -80
- data/lib/badline/media.rb +90 -81
- data/lib/badline/options/event.rb +4 -2
- data/lib/badline/options/family.rb +3 -9
- data/lib/badline/options/help.rb +2 -1
- data/lib/badline/roms/README +9 -0
- data/lib/badline/roms/dos1581.rom +0 -0
- data/lib/badline/sdl.rb +37 -20
- data/lib/badline/sid.rb +1 -1
- data/lib/badline/snapshot/machine_state.rb +9 -1
- data/lib/badline/snapshot/state.rb +6 -4
- data/lib/badline/snapshot.rb +11 -9
- data/lib/badline/storage/d64_image.rb +15 -7
- data/lib/badline/storage/disk_image/writing.rb +2 -2
- data/lib/badline/storage/disk_image.rb +1 -1
- data/lib/badline/storage/host_directory.rb +1 -1
- data/lib/badline/storage/p00.rb +8 -0
- data/lib/badline/storage/t64.rb +1 -1
- data/lib/badline/time_of_day.rb +3 -3
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic/bank.rb +1 -1
- data/lib/badline/vic/border_mask.rb +1 -1
- data/lib/badline/vic/collisions.rb +1 -1
- data/lib/badline/vic/color_patches.rb +1 -1
- data/lib/badline/vic/display_state.rb +1 -1
- data/lib/badline/vic/graphics_mode.rb +1 -1
- data/lib/badline/vic/graphics_shifter.rb +1 -1
- data/lib/badline/vic/register_log.rb +1 -1
- data/lib/badline/vic/registers.rb +1 -1
- data/lib/badline/vic/sequencer.rb +1 -1
- data/lib/badline/vic/sequencer_output.rb +1 -1
- data/lib/badline/vic/sequencer_state.rb +1 -1
- data/lib/badline/vic/sprite/internal_bus.rb +1 -1
- data/lib/badline/vic/sprite/saved_state.rb +1 -1
- data/lib/badline/vic/sprite/shifter.rb +1 -1
- data/lib/badline/vic/sprite/timing.rb +1 -1
- data/lib/badline/vic/sprite.rb +1 -1
- data/lib/badline/vic/sprites.rb +1 -1
- data/lib/badline/vic/sprites_state.rb +1 -1
- data/lib/badline/vic.rb +6 -5
- data/lib/badline/vic20/attachments.rb +15 -71
- data/lib/badline/vic20/saved_state.rb +2 -30
- data/lib/badline/vic20.rb +4 -37
- data/lib/badline/z80/core.rb +2 -0
- data/lib/badline/z80/saved_state.rb +69 -0
- metadata +61 -23
- data/lib/badline/cycleable.rb +0 -38
- /data/lib/badline/frontend/{menu_ports.rb → menu/menu_ports.rb} +0 -0
- /data/lib/badline/frontend/{player_commands.rb → player/player_commands.rb} +0 -0
- /data/lib/badline/frontend/{player_state.rb → player/player_state.rb} +0 -0
- /data/lib/badline/frontend/{sid_history.rb → player/sid_history.rb} +0 -0
|
@@ -9,13 +9,10 @@ module Badline
|
|
|
9
9
|
class MenuPages
|
|
10
10
|
include MenuPorts
|
|
11
11
|
|
|
12
|
-
TEXT = PauseMenu::TEXT
|
|
13
|
-
DIM = PauseMenu::DIM
|
|
14
12
|
LINE = 12
|
|
15
13
|
COLUMNS = 25
|
|
16
14
|
ROW_WIDTH = 200
|
|
17
15
|
|
|
18
|
-
WARNING = 0xff7a6b
|
|
19
16
|
RECENT = %i[recent0 recent1 recent2 recent3 recent4 recent5 recent6 recent7].freeze
|
|
20
17
|
|
|
21
18
|
SID_MODELS = %i[mos6581 mos8580].freeze
|
|
@@ -51,7 +48,7 @@ module Badline
|
|
|
51
48
|
|
|
52
49
|
def draw(page, left, top)
|
|
53
50
|
problem = @media.problem
|
|
54
|
-
@painter.text(left, top + 186, problem[0, COLUMNS], WARNING) unless problem.empty?
|
|
51
|
+
@painter.text(left, top + 186, problem[0, COLUMNS], MenuTheme::WARNING) unless problem.empty?
|
|
55
52
|
@left = left
|
|
56
53
|
@top = top
|
|
57
54
|
case page
|
|
@@ -95,7 +92,7 @@ module Badline
|
|
|
95
92
|
# Says in the dim colour that the VIC-20 hasn't got what the page
|
|
96
93
|
# shows.
|
|
97
94
|
def note
|
|
98
|
-
@painter.text(@left, @top, "NOT ON THE VIC-20 YET", DIM)
|
|
95
|
+
@painter.text(@left, @top, "NOT ON THE VIC-20 YET", MenuTheme::DIM)
|
|
99
96
|
end
|
|
100
97
|
|
|
101
98
|
def draw_drive
|
|
@@ -182,11 +179,11 @@ module Badline
|
|
|
182
179
|
# A label, and its value under it, or NONE in the dim colour when the
|
|
183
180
|
# value is empty.
|
|
184
181
|
def info(label, value)
|
|
185
|
-
@painter.text(@left, @top, label, DIM)
|
|
182
|
+
@painter.text(@left, @top, label, MenuTheme::DIM)
|
|
186
183
|
if value.empty?
|
|
187
|
-
@painter.text(@left, @top + LINE, "NONE", DIM)
|
|
184
|
+
@painter.text(@left, @top + LINE, "NONE", MenuTheme::DIM)
|
|
188
185
|
else
|
|
189
|
-
@painter.text(@left, @top + LINE, Painter.fit(value, COLUMNS), TEXT)
|
|
186
|
+
@painter.text(@left, @top + LINE, Painter.fit(value, COLUMNS), MenuTheme::TEXT)
|
|
190
187
|
end
|
|
191
188
|
@top += (LINE * 2) + 6
|
|
192
189
|
end
|
|
@@ -8,14 +8,8 @@ module Badline
|
|
|
8
8
|
# name and Esc leaves it.
|
|
9
9
|
class NameField
|
|
10
10
|
COLUMNS = 30
|
|
11
|
-
LETTERS = "abcdefghijklmnopqrstuvwxyz"
|
|
12
|
-
DIGITS = "1234567890"
|
|
13
11
|
OTHERS = { 44 => [" ", " "], 45 => ["-", "_"], 55 => [".", "."] }.freeze
|
|
14
12
|
|
|
15
|
-
RETURN = 40
|
|
16
|
-
ESCAPE = 41
|
|
17
|
-
BACKSPACE = 42
|
|
18
|
-
|
|
19
13
|
attr_reader :text
|
|
20
14
|
|
|
21
15
|
def initialize(painter)
|
|
@@ -47,11 +41,11 @@ module Badline
|
|
|
47
41
|
# Handles a key, and returns :done for Return, :cancel for Esc, or
|
|
48
42
|
# nil.
|
|
49
43
|
def key(scancode, shift)
|
|
50
|
-
return :done if scancode == RETURN
|
|
51
|
-
return :cancel if scancode == ESCAPE
|
|
44
|
+
return :done if scancode == Keys::RETURN
|
|
45
|
+
return :cancel if scancode == Keys::ESCAPE
|
|
52
46
|
|
|
53
47
|
@problem = ""
|
|
54
|
-
if scancode == BACKSPACE
|
|
48
|
+
if scancode == Keys::BACKSPACE
|
|
55
49
|
@text = @text[0, @text.length - 1].to_s
|
|
56
50
|
else
|
|
57
51
|
char = character(scancode, shift)
|
|
@@ -62,26 +56,19 @@ module Badline
|
|
|
62
56
|
|
|
63
57
|
def draw(left, top, width)
|
|
64
58
|
painter = @painter
|
|
65
|
-
painter.text(left, top, @title,
|
|
66
|
-
painter.box(left, top + 18, width, Buttons::HEIGHT + 4,
|
|
67
|
-
painter.text(left + 4, top + 22, "#{@text}_",
|
|
68
|
-
painter.text(left, top + 42, @problem,
|
|
69
|
-
painter.text(left, top + 60, "RETURN: SAVE ESC: CANCEL",
|
|
59
|
+
painter.text(left, top, @title, MenuTheme::BRIGHT)
|
|
60
|
+
painter.box(left, top + 18, width, Buttons::HEIGHT + 4, MenuTheme::FILL)
|
|
61
|
+
painter.text(left + 4, top + 22, "#{@text}_", MenuTheme::TEXT)
|
|
62
|
+
painter.text(left, top + 42, @problem, MenuTheme::WARNING) unless @problem.empty?
|
|
63
|
+
painter.text(left, top + 60, "RETURN: SAVE ESC: CANCEL", MenuTheme::DIM)
|
|
70
64
|
end
|
|
71
65
|
|
|
72
66
|
private
|
|
73
67
|
|
|
74
68
|
def character(scancode, shift)
|
|
75
|
-
if
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
elsif scancode.between?(30, 39)
|
|
79
|
-
DIGITS[scancode - 30]
|
|
80
|
-
elsif OTHERS.key?(scancode)
|
|
81
|
-
OTHERS[scancode][shift ? 1 : 0]
|
|
82
|
-
else
|
|
83
|
-
""
|
|
84
|
-
end
|
|
69
|
+
return OTHERS[scancode][shift ? 1 : 0] if OTHERS.key?(scancode)
|
|
70
|
+
|
|
71
|
+
Keys.character(scancode, shift)
|
|
85
72
|
end
|
|
86
73
|
end
|
|
87
74
|
end
|
|
@@ -17,30 +17,18 @@ module Badline
|
|
|
17
17
|
SECTIONS = ["SNAPSHOTS", "DRIVE 8", "DATASETTE", "EXPANSION PORT", "PORTS", "SOUND", "POWER"].freeze
|
|
18
18
|
PAGES = %i[snapshots drive datasette expansion ports sound power].freeze
|
|
19
19
|
|
|
20
|
-
PANEL = 0x1d2230
|
|
21
|
-
EDGE = 0x3a4256
|
|
22
|
-
TEXT = 0xc9d1e0
|
|
23
|
-
BRIGHT = 0xffc66d
|
|
24
|
-
DIM = 0x6b7489
|
|
25
|
-
FILL = 0x343c50
|
|
26
|
-
|
|
27
20
|
MARGIN = 16
|
|
28
21
|
WIDTH = 352
|
|
29
22
|
HEIGHT = 240
|
|
30
23
|
BODY = 138
|
|
31
24
|
|
|
32
|
-
ESCAPE = 41
|
|
33
|
-
RETURN = 40
|
|
34
|
-
SPACE = 44
|
|
35
25
|
SNAPSHOT_ACTIONS = %i[quicksave_now save_as load_save].freeze
|
|
36
|
-
ARROWS = { 79 => :right, 80 => :left, 81 => :down, 82 => :up }.freeze
|
|
37
|
-
MOUSEWHEEL = 0x403
|
|
38
26
|
|
|
39
27
|
# Takes the media, the REU and whether disks are writable from Options.
|
|
40
28
|
def initialize(painter, options, snapshots)
|
|
41
29
|
media_path = options.media_path.to_s
|
|
42
30
|
@painter = painter
|
|
43
|
-
@buttons = Buttons.new(painter, [TEXT, BRIGHT, PANEL, FILL])
|
|
31
|
+
@buttons = Buttons.new(painter, [MenuTheme::TEXT, MenuTheme::BRIGHT, MenuTheme::PANEL, MenuTheme::FILL])
|
|
44
32
|
@pages = MenuPages.new(painter, @buttons, media_path, options, snapshots)
|
|
45
33
|
@snapshots = snapshots
|
|
46
34
|
@dialogs = MenuDialogs.new(painter, @buttons, @pages.media, options, snapshots)
|
|
@@ -76,10 +64,7 @@ module Badline
|
|
|
76
64
|
# goes straight in, and anything else asks first.
|
|
77
65
|
def drop(computer, controls, sound)
|
|
78
66
|
show(computer, controls, sound)
|
|
79
|
-
|
|
80
|
-
asks = @dialogs.drop(LibC.strstr(file, ""))
|
|
81
|
-
LibC.free(file)
|
|
82
|
-
asks
|
|
67
|
+
@dialogs.drop(SDL.dropped_file)
|
|
83
68
|
end
|
|
84
69
|
|
|
85
70
|
# Handles a key pressed while the menu is open: the arrows move
|
|
@@ -91,10 +76,10 @@ module Badline
|
|
|
91
76
|
def key(scancode)
|
|
92
77
|
return :resume if scancode == Keys::F9
|
|
93
78
|
return @dialogs.key(scancode) if @dialogs.open?
|
|
94
|
-
return :resume if scancode == ESCAPE
|
|
95
|
-
return choose(@buttons.focus) if [RETURN, SPACE].include?(scancode)
|
|
79
|
+
return :resume if scancode == Keys::ESCAPE
|
|
80
|
+
return choose(@buttons.focus) if [Keys::RETURN, Keys::SPACE].include?(scancode)
|
|
96
81
|
|
|
97
|
-
direction =
|
|
82
|
+
direction = Keys::DIRECTIONS[scancode]
|
|
98
83
|
move(direction) unless direction.nil?
|
|
99
84
|
nil
|
|
100
85
|
end
|
|
@@ -134,18 +119,18 @@ module Badline
|
|
|
134
119
|
def draw
|
|
135
120
|
painter = @painter
|
|
136
121
|
@buttons.forget
|
|
137
|
-
painter.box(@left, @top, WIDTH, HEIGHT, PANEL)
|
|
138
|
-
painter.box(@left, @top + 24, WIDTH, 1, EDGE)
|
|
139
|
-
painter.text(@left + 8, @top + 9, "PAUSED", BRIGHT)
|
|
122
|
+
painter.box(@left, @top, WIDTH, HEIGHT, MenuTheme::PANEL)
|
|
123
|
+
painter.box(@left, @top + 24, WIDTH, 1, MenuTheme::EDGE)
|
|
124
|
+
painter.text(@left + 8, @top + 9, "PAUSED", MenuTheme::BRIGHT)
|
|
140
125
|
resume = "RESUME"
|
|
141
126
|
@buttons.plain(@left + WIDTH - 8 - Painter.width(resume) - (Buttons::PAD * 2), @top + 7, resume, :resume)
|
|
142
127
|
return @dialogs.draw(@left + 8, @top + 34, WIDTH - 16) if @dialogs.open?
|
|
143
128
|
|
|
144
|
-
painter.box(@left + BODY - 8, @top + 32, 1, HEIGHT - 56, EDGE)
|
|
129
|
+
painter.box(@left + BODY - 8, @top + 32, 1, HEIGHT - 56, MenuTheme::EDGE)
|
|
145
130
|
draw_sections
|
|
146
131
|
@buttons.plain(@left + 6, @top + HEIGHT - 28, "QUICK OPEN...", :quick_open)
|
|
147
|
-
painter.text(@left + 8, @top + HEIGHT - 12, "F9/ESC: RESUME", DIM)
|
|
148
|
-
painter.text(@left + BODY, @top + HEIGHT - 12, "F6: 40/80 KEY F8: SCREEN", DIM) if @pages.c128?
|
|
132
|
+
painter.text(@left + 8, @top + HEIGHT - 12, "F9/ESC: RESUME", MenuTheme::DIM)
|
|
133
|
+
painter.text(@left + BODY, @top + HEIGHT - 12, "F6: 40/80 KEY F8: SCREEN", MenuTheme::DIM) if @pages.c128?
|
|
149
134
|
@pages.draw(PAGES[@section], @left + BODY, @top + 34)
|
|
150
135
|
end
|
|
151
136
|
|
|
@@ -241,13 +226,13 @@ module Badline
|
|
|
241
226
|
when SDL::MOUSEMOTION then @buttons.point(SDL.event_x(event), SDL.event_y(event)) && nil
|
|
242
227
|
when SDL::MOUSEBUTTONDOWN
|
|
243
228
|
SDL.event_button(event) == 1 ? click(SDL.event_x(event), SDL.event_y(event)) : nil
|
|
244
|
-
when MOUSEWHEEL then @dialogs.scroll(-3 * SDL.event_x(event)) && nil
|
|
229
|
+
when SDL::MOUSEWHEEL then @dialogs.scroll(-3 * SDL.event_x(event)) && nil
|
|
245
230
|
end
|
|
246
231
|
end
|
|
247
232
|
|
|
248
233
|
# A key held down repeats only the arrows.
|
|
249
234
|
def key_down(scancode, repeat)
|
|
250
|
-
repeat.zero? ||
|
|
235
|
+
repeat.zero? || Keys::DIRECTIONS.key?(scancode) ? key(scancode) : nil
|
|
251
236
|
end
|
|
252
237
|
|
|
253
238
|
def draw_sections
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Frontend
|
|
5
|
+
# The pause menu's colours, which its pages and dialogs share. They lie
|
|
6
|
+
# outside the C64's palette, so the menu reads as the emulator's and
|
|
7
|
+
# not the machine's.
|
|
8
|
+
module MenuTheme
|
|
9
|
+
PANEL = 0x1d2230
|
|
10
|
+
EDGE = 0x3a4256
|
|
11
|
+
TEXT = 0xc9d1e0
|
|
12
|
+
BRIGHT = 0xffc66d
|
|
13
|
+
DIM = 0x6b7489
|
|
14
|
+
FILL = 0x343c50
|
|
15
|
+
WARNING = 0xff7a6b
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -6,10 +6,10 @@ module Badline
|
|
|
6
6
|
# resonance and volume, and its response across the audible range on
|
|
7
7
|
# the chip playing, whose cutoff curve the two models don't share.
|
|
8
8
|
class FilterView
|
|
9
|
-
TEXT =
|
|
10
|
-
BRIGHT =
|
|
11
|
-
DIM =
|
|
12
|
-
BOX =
|
|
9
|
+
TEXT = PlayerTheme::TEXT
|
|
10
|
+
BRIGHT = PlayerTheme::BRIGHT
|
|
11
|
+
DIM = PlayerTheme::DIM
|
|
12
|
+
BOX = PlayerTheme::BOX
|
|
13
13
|
|
|
14
14
|
MODES = ["LP", "BP", "HP", "3 OFF"].freeze
|
|
15
15
|
|
|
@@ -52,7 +52,7 @@ module Badline
|
|
|
52
52
|
def draw
|
|
53
53
|
index = 0
|
|
54
54
|
while index < ROWS && @offset + index < @lines.size
|
|
55
|
-
@painter.text(LEFT, @top + (index * LINE), @lines[@offset + index],
|
|
55
|
+
@painter.text(LEFT, @top + (index * LINE), @lines[@offset + index], PlayerTheme::TEXT)
|
|
56
56
|
index += 1
|
|
57
57
|
end
|
|
58
58
|
draw_bar if @lines.size > ROWS
|
|
@@ -110,10 +110,10 @@ module Badline
|
|
|
110
110
|
|
|
111
111
|
def draw_bar
|
|
112
112
|
@buttons.area([BAR_LEFT, @top, BAR, HEIGHT], :scroll)
|
|
113
|
-
@painter.box(BAR_LEFT, @top, BAR, HEIGHT,
|
|
113
|
+
@painter.box(BAR_LEFT, @top, BAR, HEIGHT, PlayerTheme::BOX)
|
|
114
114
|
thumb = [HEIGHT * ROWS / @lines.size, 8].max
|
|
115
115
|
place = (HEIGHT - thumb) * @offset / [last_offset, 1].max
|
|
116
|
-
@painter.box(BAR_LEFT, @top + place, BAR, thumb,
|
|
116
|
+
@painter.box(BAR_LEFT, @top + place, BAR, thumb, PlayerTheme::TEXT)
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
end
|
|
@@ -2,38 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
4
|
module Frontend
|
|
5
|
-
# The SID player
|
|
6
|
-
# a header with the tune, its STIL credit, the views and
|
|
7
|
-
# and a footer with the time and the buttons that step
|
|
8
|
-
# queue, framing one of three views: the visualizer, with
|
|
9
|
-
# note and output and the mix, the SID view, with
|
|
10
|
-
# is doing, and the tune's STIL entry. The window's
|
|
11
|
-
# view, and .sid files and folders dropped on it
|
|
5
|
+
# The SID player that `sid` plays in, which runs its window,
|
|
6
|
+
# PlayerScreen: a header with the tune, its STIL credit, the views and
|
|
7
|
+
# the SID model, and a footer with the time and the buttons that step
|
|
8
|
+
# through the queue, framing one of three views: the visualizer, with
|
|
9
|
+
# each voice's note and output and the mix, the SID view, with
|
|
10
|
+
# everything the chip is doing, and the tune's STIL entry. The window's
|
|
11
|
+
# height follows the view, and .sid files and folders dropped on it
|
|
12
|
+
# join the queue.
|
|
12
13
|
#
|
|
13
14
|
# It stands in for the terminal, so Audio::Jukebox drives it the same
|
|
14
15
|
# way: #wait handles the window's clicks, keys and drops between frames
|
|
15
16
|
# and redraws it at the display's pace. The SID model buttons switch
|
|
16
17
|
# the chips playing on the spot, and each tune after it starts on the
|
|
17
18
|
# same choice. AUTO gives each of a tune's SIDs its own model.
|
|
18
|
-
class
|
|
19
|
+
class PlayerController < Audio::Terminal
|
|
19
20
|
FRAME = 1.0 / 50
|
|
20
21
|
|
|
21
|
-
MOUSEWHEEL = 0x403
|
|
22
|
-
DROPFILE = 0x1000
|
|
23
|
-
UP = 82
|
|
24
|
-
DOWN = 81
|
|
25
|
-
|
|
26
|
-
WARNING = VIC::PALETTE[10]
|
|
27
|
-
|
|
28
22
|
CHIPS = PlayerHeader::CHIPS
|
|
29
23
|
|
|
30
24
|
KEYS = {
|
|
31
25
|
17 => :next, 19 => :previous,
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
20 => :quit,
|
|
26
|
+
Keys::RIGHT => :next_subtune, Keys::LEFT => :previous_subtune,
|
|
27
|
+
Keys::SPACE => :pause, 22 => :shuffle, 15 => :loop, 4 => :all_subtunes,
|
|
28
|
+
20 => :quit, Keys::ESCAPE => :quit,
|
|
35
29
|
54 => :back, 55 => :forward,
|
|
36
|
-
|
|
30
|
+
Keys::TAB => :view, 6 => :chip
|
|
37
31
|
}.freeze
|
|
38
32
|
|
|
39
33
|
def initialize(input:, output:)
|
|
@@ -143,17 +137,15 @@ module Badline
|
|
|
143
137
|
when SDL::MOUSEMOTION then point
|
|
144
138
|
when SDL::MOUSEBUTTONDOWN then click(actions) if SDL.event_button(SDL.event) == 1
|
|
145
139
|
when SDL::MOUSEBUTTONUP then @scrolling = false
|
|
146
|
-
when MOUSEWHEEL then @screen.info.scroll(-3 * SDL.event_x(SDL.event))
|
|
147
|
-
when DROPFILE then drop(actions)
|
|
140
|
+
when SDL::MOUSEWHEEL then @screen.info.scroll(-3 * SDL.event_x(SDL.event))
|
|
141
|
+
when SDL::DROPFILE then drop(actions)
|
|
148
142
|
end
|
|
149
143
|
end
|
|
150
144
|
actions
|
|
151
145
|
end
|
|
152
146
|
|
|
153
147
|
def drop(actions)
|
|
154
|
-
|
|
155
|
-
@dropped << LibC.strstr(file, "")
|
|
156
|
-
LibC.free(file)
|
|
148
|
+
@dropped << SDL.dropped_file
|
|
157
149
|
actions << :drop unless actions.include?(:drop)
|
|
158
150
|
end
|
|
159
151
|
|
|
@@ -164,7 +156,7 @@ module Badline
|
|
|
164
156
|
end
|
|
165
157
|
|
|
166
158
|
def key(scancode, actions)
|
|
167
|
-
return @screen.info.scroll(scancode == UP ? -1 : 1) if [UP, DOWN].include?(scancode)
|
|
159
|
+
return @screen.info.scroll(scancode == Keys::UP ? -1 : 1) if [Keys::UP, Keys::DOWN].include?(scancode)
|
|
168
160
|
|
|
169
161
|
action = KEYS[scancode]
|
|
170
162
|
command(action, actions) unless action.nil?
|
|
@@ -29,7 +29,7 @@ module Badline
|
|
|
29
29
|
x += @buttons.icon(x, row, state.paused? ? :play : :pause, :pause, scale: 2) + 4
|
|
30
30
|
x += @buttons.icon(x, row, :next, :next, scale: 2) + 8
|
|
31
31
|
unless state.tunes.zero?
|
|
32
|
-
x += @painter.text(x, row + 6, "TUNE #{state.tune}/#{state.tunes}",
|
|
32
|
+
x += @painter.text(x, row + 6, "TUNE #{state.tune}/#{state.tunes}", PlayerTheme::BRIGHT) + 24
|
|
33
33
|
draw_subtunes(state, x, row + 4)
|
|
34
34
|
end
|
|
35
35
|
draw_toggles(state, row + 4)
|
|
@@ -41,9 +41,9 @@ module Badline
|
|
|
41
41
|
private
|
|
42
42
|
|
|
43
43
|
def draw_subtunes(state, left, row)
|
|
44
|
-
x = left + @painter.text(left, row + 2, "SUBTUNE",
|
|
44
|
+
x = left + @painter.text(left, row + 2, "SUBTUNE", PlayerTheme::TEXT) + 4
|
|
45
45
|
x += @buttons.icon(x, row, :left, :previous_subtune)
|
|
46
|
-
x += @painter.text(x + 2, row + 2, "#{state.subtune}/#{state.subtunes}",
|
|
46
|
+
x += @painter.text(x + 2, row + 2, "#{state.subtune}/#{state.subtunes}", PlayerTheme::BRIGHT) + 4
|
|
47
47
|
@buttons.icon(x, row, :right, :next_subtune)
|
|
48
48
|
end
|
|
49
49
|
|
|
@@ -51,17 +51,17 @@ module Badline
|
|
|
51
51
|
played = state.played
|
|
52
52
|
width = BAR_WIDTH
|
|
53
53
|
@buttons.area([BAR_LEFT, top - 2, width, 12], :seek)
|
|
54
|
-
@painter.box(BAR_LEFT, top + 2, width, 4,
|
|
54
|
+
@painter.box(BAR_LEFT, top + 2, width, 4, PlayerTheme::BOX)
|
|
55
55
|
draw_target(state, top) if state.seeking?
|
|
56
|
-
@painter.box(BAR_LEFT, top + 2, along(state, played), 4,
|
|
56
|
+
@painter.box(BAR_LEFT, top + 2, along(state, played), 4, PlayerTheme::BRIGHT)
|
|
57
57
|
@painter.text(WIDTH - 16 - Painter.width(CLOCK), top, "#{clock(played)} / #{clock(state.length)}",
|
|
58
|
-
|
|
58
|
+
PlayerTheme::TEXT)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def draw_target(state, top)
|
|
62
62
|
target = along(state, state.target)
|
|
63
|
-
@painter.box(BAR_LEFT, top + 2, target, 4,
|
|
64
|
-
@painter.box(BAR_LEFT + [target, BAR_WIDTH - 1].min, top - 1, 1, 10,
|
|
63
|
+
@painter.box(BAR_LEFT, top + 2, target, 4, PlayerTheme::DIM)
|
|
64
|
+
@painter.box(BAR_LEFT + [target, BAR_WIDTH - 1].min, top - 1, 1, 10, PlayerTheme::BRIGHT)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
# How far along the bar `seconds` into the subtune is.
|
|
@@ -21,10 +21,10 @@ module Badline
|
|
|
21
21
|
# Underlines the models playing while AUTO picks them.
|
|
22
22
|
def draw(state, tune, playing_models, credit)
|
|
23
23
|
unless tune.nil?
|
|
24
|
-
@painter.text(16, 8, fit(tune.name, 26),
|
|
25
|
-
@painter.text(16, 28, fit([tune.author, tune.released].reject(&:empty?).join(" - "), 50),
|
|
26
|
-
@painter.text(16, 40, fit(credit, 76),
|
|
27
|
-
@painter.text(16, 52, warning(state),
|
|
24
|
+
@painter.text(16, 8, fit(tune.name, 26), PlayerTheme::BRIGHT, scale: 2)
|
|
25
|
+
@painter.text(16, 28, fit([tune.author, tune.released].reject(&:empty?).join(" - "), 50), PlayerTheme::TEXT)
|
|
26
|
+
@painter.text(16, 40, fit(credit, 76), PlayerTheme::BRIGHT)
|
|
27
|
+
@painter.text(16, 52, warning(state), PlayerTheme::WARNING)
|
|
28
28
|
end
|
|
29
29
|
draw_views(state)
|
|
30
30
|
draw_chips(state, playing_models)
|
|
@@ -48,7 +48,7 @@ module Badline
|
|
|
48
48
|
CHIP_NAMES.each_with_index do |name, chip|
|
|
49
49
|
width = @buttons.text(x, 24, name, CHIPS[chip], on: chip == state.chip)
|
|
50
50
|
if state.chip.zero? && playing_models.include?(CHIPS[chip])
|
|
51
|
-
@painter.box(x + 2, 37, width - 4, 1,
|
|
51
|
+
@painter.box(x + 2, 37, width - 4, 1, PlayerTheme::BRIGHT)
|
|
52
52
|
end
|
|
53
53
|
x += width + 4
|
|
54
54
|
end
|
|
@@ -10,7 +10,6 @@ module Badline
|
|
|
10
10
|
HEADER = 64
|
|
11
11
|
SCALE = 2
|
|
12
12
|
TITLE = "Badline"
|
|
13
|
-
BACKGROUND = VIC::PALETTE[6]
|
|
14
13
|
|
|
15
14
|
attr_reader :buttons, :info
|
|
16
15
|
|
|
@@ -72,8 +71,8 @@ module Badline
|
|
|
72
71
|
def draw(state, player, history, tune, credit)
|
|
73
72
|
return unless open?
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
back = PlayerTheme::BACKGROUND
|
|
75
|
+
SDL.SDL_SetRenderDrawColor(@renderer, (back >> 16) & 0xff, (back >> 8) & 0xff, back & 0xff, 255)
|
|
77
76
|
SDL.SDL_RenderClear(@renderer)
|
|
78
77
|
@buttons.forget
|
|
79
78
|
@top.draw(state, tune, player.nil? ? [] : player.stereo.models, credit)
|
|
@@ -90,7 +89,7 @@ module Badline
|
|
|
90
89
|
|
|
91
90
|
def build
|
|
92
91
|
@painter = Painter.new(@renderer)
|
|
93
|
-
@buttons = Buttons.new(@painter)
|
|
92
|
+
@buttons = Buttons.new(@painter, [PlayerTheme::TEXT, PlayerTheme::BRIGHT, PlayerTheme::BACKGROUND])
|
|
94
93
|
@top = PlayerHeader.new(@painter, @buttons)
|
|
95
94
|
@bottom = PlayerFooter.new(@painter, @buttons)
|
|
96
95
|
@visualizer = VisualizerView.new(@painter, HEADER + 4)
|
|
@@ -117,7 +116,7 @@ module Badline
|
|
|
117
116
|
def draw_empty(view)
|
|
118
117
|
hint = "Drop .sid files or folders here"
|
|
119
118
|
@painter.text((WIDTH - Painter.width(hint, scale: 2)) / 2, HEADER + (body_height(view) / 2) - 8, hint,
|
|
120
|
-
|
|
119
|
+
PlayerTheme::TEXT, scale: 2)
|
|
121
120
|
end
|
|
122
121
|
end
|
|
123
122
|
end
|
|
@@ -21,7 +21,7 @@ module Badline
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def draw(history, played, channel, rgb)
|
|
24
|
-
@painter.box(@left, @top, @width, @height,
|
|
24
|
+
@painter.box(@left, @top, @width, @height, PlayerTheme::BOX)
|
|
25
25
|
span = @span
|
|
26
26
|
range = @range
|
|
27
27
|
start = history.scope_start(played, span, channel)
|
|
@@ -8,13 +8,6 @@ module Badline
|
|
|
8
8
|
# a tune on more than one gets a row of buttons above the voices that
|
|
9
9
|
# pick it, which makes the view PICKER taller.
|
|
10
10
|
class SIDView
|
|
11
|
-
COLORS = VIC::PALETTE
|
|
12
|
-
TEXT = COLORS[14]
|
|
13
|
-
BRIGHT = COLORS[1]
|
|
14
|
-
DIM = COLORS[11]
|
|
15
|
-
BOX = COLORS[0]
|
|
16
|
-
VOICE_COLORS = [COLORS[7], COLORS[13], COLORS[3]].freeze
|
|
17
|
-
|
|
18
11
|
NOTES = %w[C C# D D# E F F# G G# A A# B].freeze
|
|
19
12
|
WAVES = %w[TRI SAW PUL NOI].freeze
|
|
20
13
|
FLAGS = %w[GATE SYNC RING TEST].freeze
|
|
@@ -70,9 +63,11 @@ module Badline
|
|
|
70
63
|
top = @top + (picker * PICKER)
|
|
71
64
|
frame = history.frame(played, sid)
|
|
72
65
|
3.times { |voice| draw_voice(history, frame, voice, top + (voice * VOICE_HEIGHT), clock_hz) }
|
|
73
|
-
3.times
|
|
66
|
+
3.times do |voice|
|
|
67
|
+
@voices[picker][voice].draw(history, played, (sid * 4) + voice, PlayerTheme::VOICE_COLORS[voice])
|
|
68
|
+
end
|
|
74
69
|
@filter.draw(history, frame, top + (3 * VOICE_HEIGHT) + 4, model)
|
|
75
|
-
@outputs[picker].draw(history, played, history.output(sid), BRIGHT)
|
|
70
|
+
@outputs[picker].draw(history, played, history.output(sid), PlayerTheme::BRIGHT)
|
|
76
71
|
end
|
|
77
72
|
|
|
78
73
|
private
|
|
@@ -86,13 +81,14 @@ module Badline
|
|
|
86
81
|
|
|
87
82
|
def draw_voice(history, frame, voice, top, clock_hz)
|
|
88
83
|
base = voice * 7
|
|
89
|
-
color = VOICE_COLORS[voice]
|
|
84
|
+
color = PlayerTheme::VOICE_COLORS[voice]
|
|
90
85
|
control = history.register(frame, base + 4)
|
|
91
86
|
hertz = history.hertz(frame, voice, clock_hz)
|
|
92
87
|
paint = @painter
|
|
93
88
|
paint.text(LEFT, top, "VOICE #{voice + 1}", color)
|
|
94
|
-
paint.text(LEFT, top + 12, SIDView.note(hertz), history.level(frame, voice).zero? ? DIM : color,
|
|
95
|
-
|
|
89
|
+
paint.text(LEFT, top + 12, SIDView.note(hertz), history.level(frame, voice).zero? ? PlayerTheme::DIM : color,
|
|
90
|
+
scale: 2)
|
|
91
|
+
paint.text(LEFT + 112, top + 12, format("%<hertz>.1f HZ", hertz:), PlayerTheme::TEXT)
|
|
96
92
|
draw_waves(control, top, color)
|
|
97
93
|
draw_flags(history, frame, voice, control, top + 24)
|
|
98
94
|
draw_envelope(history, frame, voice, top + 36, color)
|
|
@@ -101,17 +97,17 @@ module Badline
|
|
|
101
97
|
def draw_waves(control, top, color)
|
|
102
98
|
x = LEFT + 224
|
|
103
99
|
WAVES.each_with_index do |wave, bit|
|
|
104
|
-
x += @painter.text(x, top, wave, control[bit + 4] == 1 ? color : DIM) + 8
|
|
100
|
+
x += @painter.text(x, top, wave, control[bit + 4] == 1 ? color : PlayerTheme::DIM) + 8
|
|
105
101
|
end
|
|
106
102
|
end
|
|
107
103
|
|
|
108
104
|
def draw_flags(history, frame, voice, control, top)
|
|
109
105
|
x = LEFT + 112
|
|
110
106
|
FLAGS.each_with_index do |flag, bit|
|
|
111
|
-
x += @painter.text(x, top, flag, control[bit] == 1 ? BRIGHT : DIM) + 8
|
|
107
|
+
x += @painter.text(x, top, flag, control[bit] == 1 ? PlayerTheme::BRIGHT : PlayerTheme::DIM) + 8
|
|
112
108
|
end
|
|
113
109
|
filtered = history.register(frame, 0x17)[voice] == 1
|
|
114
|
-
@painter.text(x, top, "FILT", filtered ? BRIGHT : DIM)
|
|
110
|
+
@painter.text(x, top, "FILT", filtered ? PlayerTheme::BRIGHT : PlayerTheme::DIM)
|
|
115
111
|
end
|
|
116
112
|
|
|
117
113
|
def draw_envelope(history, frame, voice, top, color)
|
|
@@ -120,14 +116,14 @@ module Badline
|
|
|
120
116
|
sustain_release = history.register(frame, base + 6)
|
|
121
117
|
paint = @painter
|
|
122
118
|
paint.text(LEFT + 112, top, format("PW %<pw>5.1f%%", pw: pulse_width(history, frame, voice) * 100.0 / 4096),
|
|
123
|
-
TEXT)
|
|
119
|
+
PlayerTheme::TEXT)
|
|
124
120
|
rates = "A#{hex(attack_decay >> 4)} D#{hex(attack_decay & 0x0f)} " \
|
|
125
121
|
"S#{hex(sustain_release >> 4)} R#{hex(sustain_release & 0x0f)}"
|
|
126
|
-
paint.text(LEFT + 224, top, rates, TEXT)
|
|
127
|
-
paint.box(LEFT, top + 12, 128, 6, BOX)
|
|
122
|
+
paint.text(LEFT + 224, top, rates, PlayerTheme::TEXT)
|
|
123
|
+
paint.box(LEFT, top + 12, 128, 6, PlayerTheme::BOX)
|
|
128
124
|
paint.box(LEFT, top + 12, history.level(frame, voice) / 2, 6, color)
|
|
129
|
-
paint.box(LEFT + ((sustain_release >> 4) * 17 / 2), top + 10, 1, 10, BRIGHT)
|
|
130
|
-
paint.text(LEFT + 136, top + 12, PHASES.fetch(history.state(frame, voice), ""), DIM)
|
|
125
|
+
paint.box(LEFT + ((sustain_release >> 4) * 17 / 2), top + 10, 1, 10, PlayerTheme::BRIGHT)
|
|
126
|
+
paint.text(LEFT + 136, top + 12, PHASES.fetch(history.state(frame, voice), ""), PlayerTheme::DIM)
|
|
131
127
|
end
|
|
132
128
|
|
|
133
129
|
def hex(nibble) = nibble.to_s(16).upcase
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Frontend
|
|
5
|
+
# The SID player's colours, which its window and views share, from the
|
|
6
|
+
# C64's palette: one for each voice, and light blue on blue as on the
|
|
7
|
+
# machine's screen.
|
|
8
|
+
module PlayerTheme
|
|
9
|
+
TEXT = VIC::PALETTE[14]
|
|
10
|
+
BRIGHT = VIC::PALETTE[1]
|
|
11
|
+
DIM = VIC::PALETTE[11]
|
|
12
|
+
BOX = VIC::PALETTE[0]
|
|
13
|
+
BACKGROUND = VIC::PALETTE[6]
|
|
14
|
+
WARNING = VIC::PALETTE[10]
|
|
15
|
+
VOICE_COLORS = [VIC::PALETTE[7], VIC::PALETTE[13], VIC::PALETTE[3]].freeze
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -69,10 +69,10 @@ module Badline
|
|
|
69
69
|
top = row_top(count, sid)
|
|
70
70
|
scopes = @voices[count - 1]
|
|
71
71
|
3.times do |voice|
|
|
72
|
-
color =
|
|
72
|
+
color = PlayerTheme::VOICE_COLORS[voice]
|
|
73
73
|
note = SIDView.note(history.hertz(frame, voice, clock_hz))
|
|
74
74
|
silent = history.level(frame, voice).zero?
|
|
75
|
-
@painter.text(left(voice), top, note, silent ?
|
|
75
|
+
@painter.text(left(voice), top, note, silent ? PlayerTheme::DIM : color, scale: count == 1 ? 2 : 1)
|
|
76
76
|
scopes[(sid * 3) + voice].draw(history, played, (sid * 4) + voice, color)
|
|
77
77
|
end
|
|
78
78
|
draw_label(top, sid) if count > 1
|
|
@@ -80,21 +80,21 @@ module Badline
|
|
|
80
80
|
|
|
81
81
|
def draw_label(top, sid)
|
|
82
82
|
label = "SID #{sid + 1}"
|
|
83
|
-
@painter.text(SIDView::LEFT + MIX_WIDTH - Painter.width(label), top, label,
|
|
83
|
+
@painter.text(SIDView::LEFT + MIX_WIDTH - Painter.width(label), top, label, PlayerTheme::TEXT)
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
def draw_mix(history, played, count)
|
|
87
87
|
if count == 1
|
|
88
|
-
@mix.draw(history, played, SIDHistory::MIX,
|
|
88
|
+
@mix.draw(history, played, SIDHistory::MIX, PlayerTheme::BRIGHT)
|
|
89
89
|
return
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
sides = @sides[count - 2]
|
|
93
|
-
sides[0].draw(history, played, history.left,
|
|
94
|
-
sides[1].draw(history, played, history.right,
|
|
93
|
+
sides[0].draw(history, played, history.left, PlayerTheme::BRIGHT)
|
|
94
|
+
sides[1].draw(history, played, history.right, PlayerTheme::BRIGHT)
|
|
95
95
|
top = mix_top(count) + 2
|
|
96
|
-
@painter.text(SIDView::LEFT + 2, top, "L",
|
|
97
|
-
@painter.text(SIDView::LEFT + MIX_WIDTH - 10, top, "R",
|
|
96
|
+
@painter.text(SIDView::LEFT + 2, top, "L", PlayerTheme::DIM)
|
|
97
|
+
@painter.text(SIDView::LEFT + MIX_WIDTH - 10, top, "R", PlayerTheme::DIM)
|
|
98
98
|
end
|
|
99
99
|
end
|
|
100
100
|
end
|