1 // for finding memory leaks in debug mode with Visual Studio
2 #if defined _DEBUG && defined _MSC_VER
3 #include <crtdbg.h>
4 #endif
5
6 #include <stdio.h>
7 #include <stdbool.h>
8 #include "ft2_header.h"
9 #include "ft2_gui.h"
10 #include "ft2_about.h"
11 #include "ft2_video.h"
12 #include "ft2_config.h"
13 #include "ft2_audioselector.h"
14 #include "ft2_audio.h"
15 #include "ft2_help.h"
16 #include "ft2_sample_ed.h"
17 #include "ft2_nibbles.h"
18 #include "ft2_inst_ed.h"
19 #include "ft2_pattern_ed.h"
20 #include "ft2_sample_loader.h"
21 #include "ft2_diskop.h"
22 #include "ft2_wav_renderer.h"
23 #include "ft2_trim.h"
24 #include "ft2_sampling.h"
25 #include "ft2_module_loader.h"
26 #include "ft2_midi.h"
27 #include "ft2_midi.h"
28 #include "ft2_mouse.h"
29 #include "ft2_edit.h"
30 #include "ft2_sample_ed_features.h"
31 #include "ft2_palette.h"
32 #include "ft2_structs.h"
33
34 pushButton_t pushButtons[NUM_PUSHBUTTONS] =
35 {
36 // ------ RESERVED PUSHBUTTONS ------
37 { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
38
39 /*
40 ** -- STRUCT INFO: --
41 ** x = x position
42 ** y = y position
43 ** w = width
44 ** h = height
45 ** p (0,1,2) = button delay after the first trigger (f.ex. used on scrollbar buttons)
46 ** 0 = no delay, 1 = normal delay, 2 = two-phase delay
47 ** d = function call repeat delay while button is being held down (number of frames)
48 ** text #1 = text line #1
49 ** text #2 = text line #2 (if present, it will be rendered below text #1)
50 ** funcOnDown = function to call when pressed
51 ** funcOnUp = function to call when released
52 */
53
54 // ------ POSITION EDITOR PUSHBUTTONS ------
55 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
56 { 55, 2, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbPosEdPosDown, NULL },
57 { 55, 36, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbPosEdPosUp, NULL },
58 { 74, 2, 35, 16, 1, 6, "Ins.", NULL, pbPosEdIns, NULL },
59 { 74, 19, 18, 13, 1, 6, ARROW_UP_STRING, NULL, pbPosEdPattUp, NULL },
60 { 91, 19, 18, 13, 1, 6, ARROW_DOWN_STRING, NULL, pbPosEdPattDown, NULL },
61 { 74, 33, 35, 16, 1, 6, "Del.", NULL, pbPosEdDel, NULL },
62 { 74, 50, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbPosEdLenUp, NULL },
63 { 91, 50, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbPosEdLenDown, NULL },
64 { 74, 62, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbPosEdRepSUp, NULL },
65 { 91, 62, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbPosEdRepSDown, NULL },
66
67 // ------ SONG/PATTERN PUSHBUTTONS ------
68 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
69 { 168, 34, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbBPMUp, NULL },
70 { 185, 34, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbBPMDown, NULL },
71 { 168, 48, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbSpeedUp, NULL },
72 { 185, 48, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbSpeedDown, NULL },
73 { 168, 62, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbIncAdd, NULL },
74 { 185, 62, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbDecAdd, NULL },
75 { 253, 34, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbEditPattUp, NULL },
76 { 270, 34, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbEditPattDown, NULL },
77 { 253, 48, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbPattLenUp, NULL },
78 { 270, 48, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbPattLenDown, NULL },
79 { 209, 62, 40, 13, 0, 0, "Expd.", NULL, NULL, expandPattern },
80 { 248, 62, 40, 13, 0, 0, "Srnk.", NULL, NULL, shrinkPattern },
81
82 // ------ LOGO PUSHBUTTON ------
83 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
84 { 112, 0, 154, 32, 0, 0, NULL, NULL, NULL, pbToggleLogo },
85 { 266, 0, 25, 32, 0, 0, NULL, NULL, NULL, pbToggleBadge },
86
87 // ------ MAIN SCREEN PUSHBUTTONS ------
88 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
89 { 294, 2, 59, 16, 0, 0, "About", NULL, NULL, showAboutScreen },
90 { 294, 19, 59, 16, 0, 0, "Nibbles", NULL, NULL, pbNibbles },
91 { 294, 36, 59, 16, 0, 0, "Zap", NULL, NULL, pbZap },
92 { 294, 53, 59, 16, 0, 0, "Trim", NULL, NULL, toggleTrimScreen },
93 { 294, 70, 59, 16, 0, 0, "Extend", NULL, NULL, patternEditorExtended },
94 { 294, 87, 59, 16, 0, 0, "Transps.", NULL, NULL, toggleTranspose },
95 { 294, 104, 59, 16, 0, 0, "I.E.Ext.", NULL, NULL, toggleInstEditorExt },
96 { 294, 121, 59, 16, 0, 0, "S.E.Ext.", NULL, NULL, toggleSampleEditorExt },
97 { 294, 138, 59, 16, 0, 0, "Adv. Edit", NULL, NULL, toggleAdvEdit },
98 { 294, 155, 30, 16, 0, 0, "Add", NULL, NULL, pbAddChan },
99 { 323, 155, 30, 16, 0, 0, "Sub", NULL, NULL, pbSubChan },
100 { 359, 2, 59, 16, 0, 0, "Play sng.", NULL, NULL, pbPlaySong },
101 { 359, 19, 59, 16, 0, 0, "Play ptn.", NULL, NULL, pbPlayPtn },
102 { 359, 36, 59, 16, 0, 0, "Stop", NULL, NULL, stopPlaying },
103 { 359, 53, 59, 16, 0, 0, "Rec. sng.", NULL, NULL, pbRecSng },
104 { 359, 70, 59, 16, 0, 0, "Rec. ptn.", NULL, NULL, pbRecPtn },
105 { 359, 87, 59, 16, 0, 0, "Disk op.", NULL, NULL, toggleDiskOpScreen },
106 { 359, 104, 59, 16, 0, 0, "Instr. Ed.", NULL, NULL, toggleInstEditor },
107 { 359, 121, 59, 16, 0, 0, "Smp. Ed.", NULL, NULL, toggleSampleEditor },
108 { 359, 138, 59, 16, 0, 0, "Config", NULL, NULL, showConfigScreen },
109 { 359, 155, 59, 16, 0, 0, "Help", NULL, NULL, showHelpScreen },
110 { 115, 35, 46, 16, 0, 0, "Exit", NULL, NULL, exitPatternEditorExtended },
111
112 // ------ INSTRUMENT SWITCHER PUSHBUTTONS ------
113 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
114 { 590, 2, 39, 16, 0, 0, "01-08", NULL, NULL, pbSetInstrBank1 },
115 { 590, 19, 39, 16, 0, 0, "09-10", NULL, NULL, pbSetInstrBank2 },
116 { 590, 36, 39, 16, 0, 0, "11-18", NULL, NULL, pbSetInstrBank3 },
117 { 590, 53, 39, 16, 0, 0, "19-20", NULL, NULL, pbSetInstrBank4 },
118 { 590, 73, 39, 16, 0, 0, "21-28", NULL, NULL, pbSetInstrBank5 },
119 { 590, 90, 39, 16, 0, 0, "29-30", NULL, NULL, pbSetInstrBank6 },
120 { 590, 107, 39, 16, 0, 0, "31-38", NULL, NULL, pbSetInstrBank7 },
121 { 590, 124, 39, 16, 0, 0, "39-40", NULL, NULL, pbSetInstrBank8 },
122 { 590, 2, 39, 16, 0, 0, "41-48", NULL, NULL, pbSetInstrBank9 },
123 { 590, 19, 39, 16, 0, 0, "49-50", NULL, NULL, pbSetInstrBank10 },
124 { 590, 36, 39, 16, 0, 0, "51-58", NULL, NULL, pbSetInstrBank11 },
125 { 590, 53, 39, 16, 0, 0, "59-60", NULL, NULL, pbSetInstrBank12 },
126 { 590, 73, 39, 16, 0, 0, "61-68", NULL, NULL, pbSetInstrBank13,},
127 { 590, 90, 39, 16, 0, 0, "69-70", NULL, NULL, pbSetInstrBank14 },
128 { 590, 107, 39, 16, 0, 0, "71-78", NULL, NULL, pbSetInstrBank15 },
129 { 590, 124, 39, 16, 0, 0, "79-80", NULL, NULL, pbSetInstrBank16 },
130 { 590, 144, 39, 27, 0, 0, "Swap", "Bank", NULL, pbSwapInstrBank },
131 { 566, 99, 18, 13, 1, 4, ARROW_UP_STRING, NULL, sampleListScrollUp, NULL },
132 { 566, 140, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, sampleListScrollDown, NULL },
133
134 // ------ NIBBLES SCREEN PUSHBUTTONS ------
135 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
136 { 568, 104, 61, 16, 0, 0, "Play", NULL, NULL, nibblesPlay },
137 { 568, 121, 61, 16, 0, 0, "Help", NULL, NULL, nibblesHelp },
138 { 568, 138, 61, 16, 0, 0, "Highs", NULL, NULL, nibblesHighScore },
139 { 568, 155, 61, 16, 0, 0, "Exit", NULL, NULL, nibblesExit },
140
141 // ------ ADVANCED EDIT PUSHBUTTONS ------
142 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
143 { 3, 138, 51, 16, 0, 0, "Track", NULL, NULL, remapTrack },
144 { 55, 138, 52, 16, 0, 0, "Pattern", NULL, NULL, remapPattern },
145 { 3, 155, 51, 16, 0, 0, "Song", NULL, NULL, remapSong },
146 { 55, 155, 52, 16, 0, 0, "Block", NULL, NULL, remapBlock },
147
148 // ------ ABOUT SCREEN PUSHBUTTONS ------
149 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
150 { 4, 153, 59, 16, 0, 0, "Exit", NULL, NULL, exitAboutScreen },
151
152 // ------ HELP SCREEN PUSHBUTTONS ------
153 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
154 { 3, 155, 59, 16, 0, 0, "Exit", NULL, NULL, exitHelpScreen },
155 { 611, 2, 18, 13, 1, 3, ARROW_UP_STRING, NULL, helpScrollUp, NULL },
156 { 611, 158, 18, 13, 1, 3, ARROW_DOWN_STRING, NULL, helpScrollDown, NULL },
157
158 // ------ PATTERN EDITOR PUSHBUTTONS ------
159 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
160 { 3, 385, 25, 13, 1, 4, ARROW_LEFT_STRING, NULL, scrollChannelLeft, NULL },
161 { 604, 385, 25, 13, 1, 4, ARROW_RIGHT_STRING, NULL, scrollChannelRight, NULL },
162
163 // ------ TRANSPOSE PUSHBUTTONS ------
164 //x, y, w, h, p, d, text #1,text #2, funcOnDown, funcOnUp
165 { 56, 110, 21, 16, 0, 0, "up", NULL, NULL, trackTranspCurInsUp },
166 { 76, 110, 21, 16, 0, 0, "dn", NULL, NULL, trackTranspCurInsDn },
167 { 98, 110, 36, 16, 0, 0, "12up", NULL, NULL, trackTranspCurIns12Up },
168 { 133, 110, 36, 16, 0, 0, "12dn", NULL, NULL, trackTranspCurIns12Dn },
169 { 175, 110, 21, 16, 0, 0, "up", NULL, NULL, trackTranspAllInsUp },
170 { 195, 110, 21, 16, 0, 0, "dn", NULL, NULL, trackTranspAllInsDn },
171 { 217, 110, 36, 16, 0, 0, "12up", NULL, NULL, trackTranspAllIns12Up },
172 { 252, 110, 36, 16, 0, 0, "12dn", NULL, NULL, trackTranspAllIns12Dn },
173 { 56, 125, 21, 16, 0, 0, "up", NULL, NULL, pattTranspCurInsUp },
174 { 76, 125, 21, 16, 0, 0, "dn", NULL, NULL, pattTranspCurInsDn },
175 { 98, 125, 36, 16, 0, 0, "12up", NULL, NULL, pattTranspCurIns12Up },
176 { 133, 125, 36, 16, 0, 0, "12dn", NULL, NULL, pattTranspCurIns12Dn },
177 { 175, 125, 21, 16, 0, 0, "up", NULL, NULL, pattTranspAllInsUp },
178 { 195, 125, 21, 16, 0, 0, "dn", NULL, NULL, pattTranspAllInsDn },
179 { 217, 125, 36, 16, 0, 0, "12up", NULL, NULL, pattTranspAllIns12Up },
180 { 252, 125, 36, 16, 0, 0, "12dn", NULL, NULL, pattTranspAllIns12Dn },
181 { 56, 140, 21, 16, 0, 0, "up", NULL, NULL, songTranspCurInsUp },
182 { 76, 140, 21, 16, 0, 0, "dn", NULL, NULL, songTranspCurInsDn },
183 { 98, 140, 36, 16, 0, 0, "12up", NULL, NULL, songTranspCurIns12Up },
184 { 133, 140, 36, 16, 0, 0, "12dn", NULL, NULL, songTranspCurIns12Dn },
185 { 175, 140, 21, 16, 0, 0, "up", NULL, NULL, songTranspAllInsUp },
186 { 195, 140, 21, 16, 0, 0, "dn", NULL, NULL, songTranspAllInsDn },
187 { 217, 140, 36, 16, 0, 0, "12up", NULL, NULL, songTranspAllIns12Up },
188 { 252, 140, 36, 16, 0, 0, "12dn", NULL, NULL, songTranspAllIns12Dn },
189 { 56, 155, 21, 16, 0, 0, "up", NULL, NULL, blockTranspCurInsUp },
190 { 76, 155, 21, 16, 0, 0, "dn", NULL, NULL, blockTranspCurInsDn },
191 { 98, 155, 36, 16, 0, 0, "12up", NULL, NULL, blockTranspCurIns12Up },
192 { 133, 155, 36, 16, 0, 0, "12dn", NULL, NULL, blockTranspCurIns12Dn },
193 { 175, 155, 21, 16, 0, 0, "up", NULL, NULL, blockTranspAllInsUp },
194 { 195, 155, 21, 16, 0, 0, "dn", NULL, NULL, blockTranspAllInsDn },
195 { 217, 155, 36, 16, 0, 0, "12up", NULL, NULL, blockTranspAllIns12Up },
196 { 252, 155, 36, 16, 0, 0, "12dn", NULL, NULL, blockTranspAllIns12Dn },
197
198 // ------ SAMPLE EDITOR PUSHBUTTONS ------
199 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
200 { 3, 331, 23, 13, 1, 3, ARROW_LEFT_STRING, NULL, scrollSampleDataLeft, NULL },
201 { 606, 331, 23, 13, 1, 3, ARROW_RIGHT_STRING, NULL, scrollSampleDataRight, NULL },
202 { 38, 356, 18, 13, 1, 4, ARROW_UP_STRING, NULL, sampPlayNoteUp, NULL },
203 { 38, 368, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, sampPlayNoteDown, NULL },
204 { 3, 382, 53, 16, 0, 0, "Stop", NULL, NULL, smpEdStop},
205 { 57, 348, 55, 16, 0, 0, "Wave", NULL, NULL, sampPlayWave },
206 { 57, 365, 55, 16, 0, 0, "Range", NULL, NULL, sampPlayRange },
207 { 57, 382, 55, 16, 0, 0, "Display", NULL, NULL, sampPlayDisplay },
208 { 118, 348, 63, 16, 0, 0, "Show r.", NULL, NULL, showRange },
209 { 118, 365, 63, 16, 0, 0, "Range all", NULL, NULL, rangeAll },
210 { 118, 382, 63, 16, 0, 0, "Sample", NULL, NULL, startSampling },
211 { 182, 348, 63, 16, 0, 0, "Zoom out", NULL, NULL, zoomOut },
212 { 182, 365, 63, 16, 0, 0, "Show all", NULL, NULL, showAll },
213 { 182, 382, 63, 16, 0, 0, "Save rng.", NULL, NULL, saveRange },
214 { 251, 348, 43, 16, 0, 0, "Cut", NULL, NULL, sampCut },
215 { 251, 365, 43, 16, 0, 0, "Copy", NULL, NULL, sampCopy },
216 { 251, 382, 43, 16, 0, 0, "Paste", NULL, NULL, sampPaste },
217 { 300, 348, 50, 16, 0, 0, "Crop", NULL, NULL, sampCrop },
218 { 300, 365, 50, 16, 0, 0, "Volume", NULL, NULL, pbSampleVolume },
219 { 300, 382, 50, 16, 0, 0, "X-Fade", NULL, NULL, sampXFade },
220 { 430, 348, 54, 16, 0, 0, "Exit", NULL, NULL, exitSampleEditor },
221 { 594, 348, 35, 13, 0, 0, "Clr S.", NULL, NULL, clearSample },
222 { 594, 360, 35, 13, 0, 0, "Min.", NULL, NULL, sampMinimize },
223 { 594, 373, 18, 13, 2, 4, ARROW_UP_STRING, NULL, sampRepeatUp, NULL },
224 { 611, 373, 18, 13, 2, 4, ARROW_DOWN_STRING, NULL, sampRepeatDown, NULL },
225 { 594, 385, 18, 13, 2, 4, ARROW_UP_STRING, NULL, sampReplenUp, NULL },
226 { 611, 385, 18, 13, 2, 4, ARROW_DOWN_STRING, NULL, sampReplenDown, NULL },
227
228 // ------ SAMPLE EDITOR EXTENSION PUSHBUTTONS ------
229 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
230 { 3, 138, 52, 16, 0, 0, "Clr. c.bf", NULL, NULL, clearCopyBuffer },
231 { 56, 138, 49, 16, 0, 0, "Sign", NULL, NULL, sampleChangeSign },
232 { 106, 138, 49, 16, 0, 0, "Echo", NULL, NULL, pbSampleEcho },
233 { 3, 155, 52, 16, 0, 0, "Backw.", NULL, NULL, sampleBackwards },
234 { 56, 155, 49, 16, 0, 0, "B. swap", NULL, NULL, sampleByteSwap },
235 { 106, 155, 49, 16, 0, 0, "Fix DC", NULL, NULL, fixDC },
236 { 161, 121, 60, 16, 0, 0, "Copy ins.", NULL, NULL, copyInstr },
237 { 222, 121, 66, 16, 0, 0, "Copy smp.", NULL, NULL, copySmp },
238 { 161, 138, 60, 16, 0, 0, "Xchg ins.", NULL, NULL, xchgInstr },
239 { 222, 138, 66, 16, 0, 0, "Xchg smp.", NULL, NULL, xchgSmp },
240 { 161, 155, 60, 16, 0, 0, "Resample", NULL, NULL, pbSampleResample },
241 { 222, 155, 66, 16, 0, 0, "Mix smp.", NULL, NULL, pbSampleMix },
242
243 // ------ INSTRUMENT EDITOR PUSHBUTTONS ------
244 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
245 { 200, 175, 23, 12, 0, 0, SMALL_1_STRING, NULL, NULL, volPreDef1 },
246 { 222, 175, 24, 12, 0, 0, SMALL_2_STRING, NULL, NULL, volPreDef2 },
247 { 245, 175, 24, 12, 0, 0, SMALL_3_STRING, NULL, NULL, volPreDef3 },
248 { 268, 175, 24, 12, 0, 0, SMALL_4_STRING, NULL, NULL, volPreDef4 },
249 { 291, 175, 24, 12, 0, 0, SMALL_5_STRING, NULL, NULL, volPreDef5 },
250 { 314, 175, 24, 12, 0, 0, SMALL_6_STRING, NULL, NULL, volPreDef6 },
251 { 200, 262, 23, 12, 0, 0, SMALL_1_STRING, NULL, NULL, panPreDef1 },
252 { 222, 262, 24, 12, 0, 0, SMALL_2_STRING, NULL, NULL, panPreDef2 },
253 { 245, 262, 24, 12, 0, 0, SMALL_3_STRING, NULL, NULL, panPreDef3 },
254 { 268, 262, 24, 12, 0, 0, SMALL_4_STRING, NULL, NULL, panPreDef4 },
255 { 291, 262, 24, 12, 0, 0, SMALL_5_STRING, NULL, NULL, panPreDef5 },
256 { 314, 262, 24, 12, 0, 0, SMALL_6_STRING, NULL, NULL, panPreDef6 },
257 { 570, 276, 59, 16, 0, 0, "Exit", NULL, NULL, exitInstEditor },
258 { 341, 175, 47, 16, 1, 4, "Add", NULL, volEnvAdd, NULL },
259 { 389, 175, 46, 16, 1, 4, "Del", NULL, volEnvDel, NULL },
260 { 398, 204, 19, 13, 1, 4, ARROW_UP_STRING, NULL, volEnvSusUp, NULL },
261 { 416, 204, 19, 13, 1, 4, ARROW_DOWN_STRING, NULL, volEnvSusDown, NULL },
262 { 398, 231, 19, 13, 1, 4, ARROW_UP_STRING, NULL, volEnvRepSUp, NULL },
263 { 416, 231, 19, 13, 1, 4, ARROW_DOWN_STRING, NULL, volEnvRepSDown, NULL },
264 { 398, 245, 19, 13, 1, 4, ARROW_UP_STRING, NULL, volEnvRepEUp, NULL },
265 { 416, 245, 19, 13, 1, 4, ARROW_DOWN_STRING, NULL, volEnvRepEDown, NULL },
266 { 341, 262, 47, 16, 1, 4, "Add", NULL, panEnvAdd, NULL },
267 { 389, 262, 46, 16, 1, 4, "Del", NULL, panEnvDel, NULL },
268 { 398, 291, 19, 13, 1, 4, ARROW_UP_STRING, NULL, panEnvSusUp, NULL },
269 { 416, 291, 19, 13, 1, 4, ARROW_DOWN_STRING, NULL, panEnvSusDown, NULL },
270 { 398, 318, 19, 13, 1, 4, ARROW_UP_STRING, NULL, panEnvRepSUp, NULL },
271 { 416, 318, 19, 13, 1, 4, ARROW_DOWN_STRING, NULL, panEnvRepSDown, NULL },
272 { 398, 332, 19, 13, 1, 4, ARROW_UP_STRING, NULL, panEnvRepEUp, NULL },
273 { 416, 332, 19, 13, 1, 4, ARROW_DOWN_STRING, NULL, panEnvRepEDown, NULL },
274 { 521, 175, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, volDown, NULL },
275 { 606, 175, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, volUp, NULL },
276 { 521, 189, 23, 13, 2, 4, ARROW_LEFT_STRING, NULL, panDown, NULL },
277 { 606, 189, 23, 13, 2, 4, ARROW_RIGHT_STRING, NULL, panUp, NULL },
278 { 521, 203, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, ftuneDown, NULL },
279 { 606, 203, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, ftuneUp, NULL },
280 { 521, 220, 23, 13, 2, 4, ARROW_LEFT_STRING, NULL, fadeoutDown, NULL },
281 { 606, 220, 23, 13, 2, 4, ARROW_RIGHT_STRING, NULL, fadeoutUp, NULL },
282 { 521, 234, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, vibSpeedDown, NULL },
283 { 606, 234, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, vibSpeedUp, NULL },
284 { 521, 248, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, vibDepthDown, NULL },
285 { 606, 248, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, vibDepthUp, NULL },
286 { 521, 262, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, vibSweepDown, NULL },
287 { 606, 262, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, vibSweepUp, NULL },
288 { 441, 312, 94, 16, 1, 4, "Octave up", NULL, relativeNoteOctUp, NULL },
289 { 536, 312, 93, 16, 1, 4, "Halftone up", NULL, relativeNoteUp, NULL },
290 { 441, 329, 94, 16, 1, 4, "Octave down", NULL, relativeNoteOctDown, NULL },
291 { 536, 329, 93, 16, 1, 4, "Halftone down", NULL, relativeNoteDown, NULL },
292
293 // ------ INSTRUMENT EDITOR EXTENSION PUSHBUTTONS ------
294 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
295 { 172, 130, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, midiChDown, NULL },
296 { 265, 130, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, midiChUp, NULL },
297 { 172, 144, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, midiPrgDown, NULL },
298 { 265, 144, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, midiPrgUp, NULL },
299 { 172, 158, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, midiBendDown, NULL },
300 { 265, 158, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, midiBendUp, NULL },
301
302 // ------ TRIM SCREEN PUSHBUTTONS ------
303 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
304 { 139, 155, 74, 16, 0, 0, "Calculate", NULL, NULL, pbTrimCalc },
305 { 214, 155, 74, 16, 0, 0, "Trim", NULL, NULL, pbTrimDoTrim },
306
307 // ------ CONFIG LEFT PANEL PUSHBUTTONS ------
308 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
309 { 3, 104, 104, 16, 0, 0, "Reset config", NULL, NULL, resetConfig },
310 { 3, 121, 104, 16, 0, 0, "Load config", NULL, NULL, loadConfig2 },
311 { 3, 138, 104, 16, 0, 0, "Save config", NULL, NULL, saveConfig2 },
312 { 3, 155, 104, 16, 0, 0, "Exit", NULL, NULL, exitConfigScreen },
313
314 // ------ CONFIG AUDIO PUSHBUTTONS ------
315 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
316 { 326, 2, 57, 13, 0, 0, "Re-scan", NULL, NULL, rescanAudioDevices },
317 { 365, 16, 18, 13, 1, 4, ARROW_UP_STRING, NULL, scrollAudOutputDevListUp, NULL },
318 { 365, 72, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, scrollAudOutputDevListDown, NULL },
319 { 365, 103, 18, 13, 1, 4, ARROW_UP_STRING, NULL, scrollAudInputDevListUp, NULL },
320 { 365, 137, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, scrollAudInputDevListDown, NULL },
321 { 508, 132, 21, 13, 1, 4, ARROW_LEFT_STRING, NULL, configAmpDown, NULL },
322 { 608, 132, 21, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configAmpUp, NULL },
323 { 508, 158, 21, 13, 1, 0, ARROW_LEFT_STRING, NULL, configMasterVolDown, NULL },
324 { 608, 158, 21, 13, 1, 0, ARROW_RIGHT_STRING, NULL, configMasterVolUp, NULL },
325
326 // ------ CONFIG LAYOUT PUSHBUTTONS ------
327 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
328 { 513, 15, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, configPalRDown, NULL },
329 { 606, 15, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configPalRUp, NULL },
330 { 513, 29, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, configPalGDown, NULL },
331 { 606, 29, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configPalGUp, NULL },
332 { 513, 43, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, configPalBDown, NULL },
333 { 606, 43, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configPalBUp, NULL },
334 { 513, 71, 23, 13, 1, 4, ARROW_LEFT_STRING, NULL, configPalContDown, NULL },
335 { 606, 71, 23, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configPalContUp, NULL },
336
337 // ------ CONFIG MISCELLANEOUS PUSHBUTTONS ------
338 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
339 { 370, 121, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configQuantizeUp, NULL },
340 { 387, 121, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configQuantizeDown, NULL },
341 { 594, 106, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configMIDIChnUp, NULL },
342 { 611, 106, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configMIDIChnDown, NULL },
343 { 594, 120, 18, 13, 1, 4, ARROW_UP_STRING, NULL, configMIDITransUp, NULL },
344 { 611, 120, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, configMIDITransDown, NULL },
345 { 556, 158, 22, 13, 1, 4, ARROW_LEFT_STRING, NULL, configMIDISensDown, NULL },
346 { 607, 158, 22, 13, 1, 4, ARROW_RIGHT_STRING, NULL, configMIDISensUp, NULL },
347
348 #ifdef HAS_MIDI
349 // ------ CONFIG MIDI PUSHBUTTONS ------
350 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
351 { 483, 2, 18, 13, 1, 4, ARROW_UP_STRING, NULL, scrollMidiInputDevListUp, NULL },
352 { 483, 158, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, scrollMidiInputDevListDown, NULL },
353 #endif
354
355 // ------ DISK OP. PUSHBUTTONS ------
356 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
357 { 70, 2, 58, 16, 0, 0, "Save", NULL, NULL, pbDiskOpSave },
358 { 70, 19, 58, 16, 0, 0, "Delete", NULL, NULL, pbDiskOpDelete },
359 { 70, 36, 58, 16, 0, 0, "Rename", NULL, NULL, pbDiskOpRename },
360 { 70, 53, 58, 16, 0, 0, "Make dir.", NULL, NULL, pbDiskOpMakeDir },
361 { 70, 70, 58, 16, 0, 0, "Refresh", NULL, NULL, pbDiskOpRefresh },
362 { 70, 87, 58, 16, 0, 0, "Set path", NULL, NULL, pbDiskOpSetPath },
363 { 70, 104, 58, 16, 0, 0, "Show all", NULL, NULL, pbDiskOpShowAll },
364 { 70, 121, 58, 19, 0, 0, "Exit", NULL, NULL, pbDiskOpExit },
365 #ifdef _WIN32 // partition letters
366 { 134, 2, 31, 13, 0, 0, ".\001", NULL, NULL, pbDiskOpParent },
367 { 134, 16, 31, 12, 0, 0, "\\", NULL, NULL, pbDiskOpRoot },
368 { 134, 29, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive1 },
369 { 134, 43, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive2 },
370 { 134, 57, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive3 },
371 { 134, 71, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive4 },
372 { 134, 85, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive5 },
373 { 134, 99, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive6 },
374 { 134, 113, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive7 },
375 { 134, 127, 31, 13, 0, 0, NULL, NULL, NULL, pbDiskOpDrive8 },
376 #else
377 { 134, 2, 31, 13, 0, 0, "../", NULL, NULL, pbDiskOpParent },
378 { 134, 16, 31, 12, 0, 0, "/", NULL, NULL, pbDiskOpRoot },
379 #endif
380 { 335, 2, 18, 13, 1, 3, ARROW_UP_STRING, NULL, pbDiskOpListUp, NULL },
381 { 335, 158, 18, 13, 1, 3, ARROW_DOWN_STRING, NULL, pbDiskOpListDown, NULL },
382
383 // ------ WAV RENDERER PUSHBUTTONS ------
384 //x, y, w, h, p, d, text #1, text #2, funcOnDown, funcOnUp
385 { 3, 111, 73, 43, 0, 0, "Export", NULL, NULL, pbWavRender },
386 { 3, 155, 73, 16, 0, 0, "Exit", NULL, NULL, pbWavExit },
387 { 253, 114, 18, 13, 1, 6, ARROW_UP_STRING, NULL, pbWavFreqUp, NULL },
388 { 270, 114, 18, 13, 1, 6, ARROW_DOWN_STRING, NULL, pbWavFreqDown, NULL },
389 { 253, 128, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbWavAmpUp, NULL },
390 { 270, 128, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbWavAmpDown, NULL },
391 { 253, 142, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbWavSongStartUp, NULL },
392 { 270, 142, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbWavSongStartDown, NULL },
393 { 253, 156, 18, 13, 1, 4, ARROW_UP_STRING, NULL, pbWavSongEndUp, NULL },
394 { 270, 156, 18, 13, 1, 4, ARROW_DOWN_STRING, NULL, pbWavSongEndDown, NULL }
395 };
396
397 static uint32_t tmpCounter;
398
drawPushButton(uint16_t pushButtonID)399 void drawPushButton(uint16_t pushButtonID)
400 {
401 uint16_t textX, textY, textW;
402
403 assert(pushButtonID < NUM_PUSHBUTTONS);
404
405 pushButton_t *b = &pushButtons[pushButtonID];
406 if (!b->visible)
407 return;
408
409 uint8_t state = b->state;
410
411 uint16_t x = b->x;
412 uint16_t y = b->y;
413 uint16_t w = b->w;
414 uint16_t h = b->h;
415
416 assert(x < SCREEN_W && y < SCREEN_H && w >= 4 && h >= 4);
417
418 if (b->bitmapFlag)
419 {
420 blitFast(x, y, (state == PUSHBUTTON_UNPRESSED) ? b->bitmapUnpressed : b->bitmapPressed, w, h);
421 return;
422 }
423
424 // fill button background
425 fillRect(x + 1, y + 1, w - 2, h - 2, PAL_BUTTONS);
426
427 // draw outer border
428 hLine(x, y, w, PAL_BCKGRND);
429 hLine(x, y + h - 1, w, PAL_BCKGRND);
430 vLine(x, y, h, PAL_BCKGRND);
431 vLine(x + w - 1, y, h, PAL_BCKGRND);
432
433 //draw inner borders
434 if (state == PUSHBUTTON_UNPRESSED)
435 {
436 // top left corner inner border
437 hLine(x + 1, y + 1, w - 3, PAL_BUTTON1);
438 vLine(x + 1, y + 2, h - 4, PAL_BUTTON1);
439
440 // bottom right corner inner border
441 hLine(x + 1 - 0, y + h - 2, w - 2, PAL_BUTTON2);
442 vLine(x + w - 2, y + 1 - 0, h - 3, PAL_BUTTON2);
443 }
444 else
445 {
446 // top left corner inner border
447 hLine(x + 1, y + 1, w - 2, PAL_BUTTON2);
448 vLine(x + 1, y + 2, h - 3, PAL_BUTTON2);
449 }
450
451 // render button text(s)
452 if (b->caption != NULL && *b->caption != '\0')
453 {
454 // button text #2
455 if (b->caption2 != NULL && *b->caption2 != '\0')
456 {
457 textW = textWidth(b->caption2);
458 textX = x + ((w - textW) / 2);
459 textY = y + 6 + ((h - (FONT1_CHAR_H - 2)) / 2);
460
461 if (state == PUSHBUTTON_PRESSED)
462 textOut(textX + 1, textY + 1, PAL_BTNTEXT, b->caption2);
463 else
464 textOut(textX, textY, PAL_BTNTEXT, b->caption2);
465
466 y -= 5; // if two text lines, bias y position of first (upper) text
467 }
468
469 // button text #1
470 textW = textWidth(b->caption);
471 textX = x + ((w - textW) / 2);
472 textY = y + ((h - (FONT1_CHAR_H - 2)) / 2);
473
474 if (state == PUSHBUTTON_PRESSED)
475 textOut(textX + 1, textY + 1, PAL_BTNTEXT, b->caption);
476 else
477 textOut(textX, textY, PAL_BTNTEXT, b->caption);
478 }
479 }
480
showPushButton(uint16_t pushButtonID)481 void showPushButton(uint16_t pushButtonID)
482 {
483 assert(pushButtonID < NUM_PUSHBUTTONS);
484 pushButtons[pushButtonID].visible = true;
485 drawPushButton(pushButtonID);
486 }
487
hidePushButton(uint16_t pushButtonID)488 void hidePushButton(uint16_t pushButtonID)
489 {
490 assert(pushButtonID < NUM_PUSHBUTTONS);
491 pushButtons[pushButtonID].state = 0;
492 pushButtons[pushButtonID].visible = false;
493 }
494
handlePushButtonsWhileMouseDown(void)495 void handlePushButtonsWhileMouseDown(void)
496 {
497 int8_t buttonDelay;
498
499 assert(mouse.lastUsedObjectID >= 0 && mouse.lastUsedObjectID < NUM_PUSHBUTTONS);
500 pushButton_t *pushButton = &pushButtons[mouse.lastUsedObjectID];
501 if (!pushButton->visible)
502 return;
503
504 pushButton->state = PUSHBUTTON_UNPRESSED;
505 if (mouse.x >= pushButton->x && mouse.x < pushButton->x+pushButton->w &&
506 mouse.y >= pushButton->y && mouse.y < pushButton->y+pushButton->h)
507 {
508 pushButton->state = PUSHBUTTON_PRESSED;
509 }
510
511 if (mouse.lastX != mouse.x || mouse.lastY != mouse.y)
512 {
513 mouse.lastX = mouse.x;
514 mouse.lastY = mouse.y;
515
516 drawPushButton(mouse.lastUsedObjectID);
517 }
518
519 // long delay before repeat
520 if (pushButton->preDelay && mouse.firstTimePressingButton)
521 {
522 tmpCounter = 0;
523
524 if (++mouse.buttonCounter >= BUTTON_DOWN_DELAY)
525 {
526 mouse.buttonCounter = 0;
527 mouse.firstTimePressingButton = false;
528 }
529 else
530 {
531 return; // we're delaying
532 }
533 }
534
535 if (pushButton->state == PUSHBUTTON_PRESSED)
536 {
537 // button delay stuff
538 if (mouse.rightButtonPressed)
539 buttonDelay = pushButton->delayFrames >> 1;
540 else if (pushButton->preDelay == 2 && (!mouse.firstTimePressingButton && ++tmpCounter >= 50)) // special mode
541 buttonDelay = 0;
542 else
543 buttonDelay = pushButton->delayFrames;
544
545 // main repeat delay
546 if (++mouse.buttonCounter >= buttonDelay)
547 {
548 mouse.buttonCounter = 0;
549 if (pushButton->callbackFuncOnDown != NULL)
550 pushButton->callbackFuncOnDown();
551 }
552 }
553 }
554
testPushButtonMouseDown(void)555 bool testPushButtonMouseDown(void)
556 {
557 uint16_t start, end;
558
559 if (ui.sysReqShown)
560 {
561 // if a system request is open, only test the first eight pushbuttons (reserved)
562 start = 0;
563 end = 8;
564 }
565 else
566 {
567 start = 8;
568 end = NUM_PUSHBUTTONS;
569 }
570
571 pushButton_t *pushButton = &pushButtons[start];
572 for (uint16_t i = start; i < end; i++, pushButton++)
573 {
574 if (!pushButton->visible)
575 continue;
576
577 if (mouse.x >= pushButton->x && mouse.x < pushButton->x+pushButton->w &&
578 mouse.y >= pushButton->y && mouse.y < pushButton->y+pushButton->h)
579 {
580 mouse.lastUsedObjectID = i;
581 mouse.lastUsedObjectType = OBJECT_PUSHBUTTON;
582
583 if (!mouse.rightButtonPressed)
584 {
585 mouse.firstTimePressingButton = true;
586 mouse.buttonCounter = 0;
587
588 pushButton->state = PUSHBUTTON_PRESSED;
589 drawPushButton(i);
590
591 if (pushButton->callbackFuncOnDown != NULL)
592 pushButton->callbackFuncOnDown();
593 }
594
595 return true;
596 }
597 }
598
599 return false;
600 }
601
testPushButtonMouseRelease(bool runCallback)602 int16_t testPushButtonMouseRelease(bool runCallback)
603 {
604 if (mouse.lastUsedObjectType != OBJECT_PUSHBUTTON || mouse.lastUsedObjectID == OBJECT_ID_NONE)
605 return -1;
606
607 assert(mouse.lastUsedObjectID < NUM_PUSHBUTTONS);
608 pushButton_t *pushButton = &pushButtons[mouse.lastUsedObjectID];
609 if (!pushButton->visible)
610 return -1;
611
612 if (mouse.x >= pushButton->x && mouse.x < pushButton->x+pushButton->w &&
613 mouse.y >= pushButton->y && mouse.y < pushButton->y+pushButton->h)
614 {
615 pushButton->state = PUSHBUTTON_UNPRESSED;
616 drawPushButton(mouse.lastUsedObjectID);
617
618 if (runCallback)
619 {
620 if (pushButton->callbackFuncOnUp != NULL)
621 pushButton->callbackFuncOnUp();
622 }
623
624 return mouse.lastUsedObjectID;
625 }
626
627 return -1;
628 }
629