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 <stdint.h>
7 #include <stdbool.h>
8 #include "ft2_header.h"
9 #include "ft2_gui.h"
10 #include "ft2_config.h"
11 #include "ft2_audio.h"
12 #include "ft2_help.h"
13 #include "ft2_sample_ed.h"
14 #include "ft2_inst_ed.h"
15 #include "ft2_diskop.h"
16 #include "ft2_pattern_ed.h"
17 #include "ft2_audioselector.h"
18 #include "ft2_midi.h"
19 #include "ft2_mouse.h"
20 #include "ft2_video.h"
21 #include "ft2_palette.h"
22 #include "ft2_structs.h"
23
24 /* Prevent the scrollbar thumbs from being so small that
25 ** it's difficult to use them. In units of pixels.
26 ** Shouldn't be higher than 9!
27 */
28 #define MIN_THUMB_LENGTH 5
29
30 scrollBar_t scrollBars[NUM_SCROLLBARS] =
31 {
32 // ------ RESERVED SCROLLBARS ------
33 { 0 }, { 0 }, { 0 },
34
35 /*
36 ** -- STRUCT INFO: --
37 ** x = x position
38 ** y = y position
39 ** w = width
40 ** h = height
41 ** type = scrollbar type (vertical/horizontal)
42 ** style = scrollbar style (flat/noflat)
43 ** funcOnDown = function to call when pressed
44 */
45
46 // ------ POSITION EDITOR SCROLLBARS ------
47 //x, y, w, h, type, style funcOnDown
48 { 55, 15, 18, 21, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, sbPosEdPos },
49
50 // ------ INSTRUMENT SWITCHER SCROLLBARS ------
51 //x, y, w, h, type, style funcOnDown
52 { 566, 112, 18, 28, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, sbSmpBankPos },
53
54 // ------ PATTERN VIEWER SCROLLBARS ------
55 //x, y, w, h, type, style funcOnDown
56 { 28, 385, 576, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_FLAT, setChannelScrollPos },
57
58 // ------ HELP SCREEN SCROLLBARS ------
59 //x, y, w, h, type, style funcOnDown
60 { 611, 15, 18, 143, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, helpScrollSetPos },
61
62 // ------ SAMPLE EDITOR SCROLLBARS ------
63 //x, y, w, h, type, style funcOnDown
64 { 26, 331, 580, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_FLAT, scrollSampleData },
65
66 // ------ INSTRUMENT EDITOR SCROLLBARS ------
67 //x, y, w, h, type, style funcOnDown
68 { 544, 175, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setVolumeScroll },
69 { 544, 189, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setPanningScroll },
70 { 544, 203, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setFinetuneScroll },
71 { 544, 220, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setFadeoutScroll },
72 { 544, 234, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setVibSpeedScroll },
73 { 544, 248, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setVibDepthScroll },
74 { 544, 262, 62, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, setVibSweepScroll },
75
76 // ------ INSTRUMENT EDITOR EXTENSION SCROLLBARS ------
77 //x, y, w, h, type, style funcOnDown
78 { 195, 130, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbMidiChPos },
79 { 195, 144, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbMidiPrgPos },
80 { 195, 158, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbMidiBendPos },
81
82 // ------ CONFIG AUDIO SCROLLBARS ------
83 //x, y, w, h, type, style funcOnDown
84 { 365, 29, 18, 43, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, sbAudOutputSetPos },
85 { 365, 116, 18, 21, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, sbAudInputSetPos },
86 { 529, 132, 79, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbAmp },
87 { 529, 158, 79, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbMasterVol },
88
89 // ------ CONFIG LAYOUT SCROLLBARS ------
90 //x, y, w, h, type, style funcOnDown
91 { 536, 15, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbPalRPos },
92 { 536, 29, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbPalGPos },
93 { 536, 43, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbPalBPos },
94 { 536, 71, 70, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbPalContrastPos },
95
96 // ------ CONFIG MISCELLANEOUS SCROLLBARS ------
97 //x, y, w, h, type, style funcOnDown
98 { 578, 158, 29, 13, SCROLLBAR_HORIZONTAL, SCROLLBAR_THUMB_NOFLAT, sbMIDISens },
99
100 #ifdef HAS_MIDI
101 // ------ CONFIG MIDI SCROLLBARS ------
102 //x, y, w, h, type, style funcOnDown
103 { 483, 15, 18, 143, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, sbMidiInputSetPos },
104 #endif
105
106 // ------ DISK OP. SCROLLBARS ------
107 //x, y, w, h, type, style funcOnDown
108 { 335, 15, 18, 143, SCROLLBAR_VERTICAL, SCROLLBAR_THUMB_FLAT, sbDiskOpSetPos }
109 };
110
drawScrollBar(uint16_t scrollBarID)111 void drawScrollBar(uint16_t scrollBarID)
112 {
113 assert(scrollBarID < NUM_SCROLLBARS);
114 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
115 if (!scrollBar->visible)
116 return;
117
118 assert(scrollBar->x < SCREEN_W && scrollBar->y < SCREEN_H && scrollBar->w >= 3 && scrollBar->h >= 3);
119
120 int16_t thumbX = scrollBar->thumbX;
121 int16_t thumbY = scrollBar->thumbY;
122 int16_t thumbW = scrollBar->thumbW;
123 int16_t thumbH = scrollBar->thumbH;
124
125 // clear scrollbar background (lazy, but sometimes even faster than filling bg gaps)
126 clearRect(scrollBar->x, scrollBar->y, scrollBar->w, scrollBar->h);
127
128 // draw thumb
129 if (scrollBar->thumbType == SCROLLBAR_THUMB_FLAT)
130 {
131 // flat
132 fillRect(thumbX, thumbY, thumbW, thumbH, PAL_PATTEXT);
133 }
134 else
135 {
136 // 3D
137 fillRect(thumbX, thumbY, thumbW, thumbH, PAL_BUTTONS);
138
139 if (scrollBar->state == SCROLLBAR_UNPRESSED)
140 {
141 // top left corner inner border
142 hLine(thumbX, thumbY, thumbW - 1, PAL_BUTTON1);
143 vLine(thumbX, thumbY + 1, thumbH - 2, PAL_BUTTON1);
144
145 // bottom right corner inner border
146 hLine(thumbX, thumbY + thumbH - 1, thumbW - 1, PAL_BUTTON2);
147 vLine(thumbX + thumbW - 1, thumbY, thumbH, PAL_BUTTON2);
148 }
149 else
150 {
151 // top left corner inner border
152 hLine(thumbX, thumbY, thumbW, PAL_BUTTON2);
153 vLine(thumbX, thumbY + 1, thumbH - 1, PAL_BUTTON2);
154 }
155 }
156 }
157
showScrollBar(uint16_t scrollBarID)158 void showScrollBar(uint16_t scrollBarID)
159 {
160 assert(scrollBarID < NUM_SCROLLBARS);
161 scrollBars[scrollBarID].visible = true;
162 drawScrollBar(scrollBarID);
163 }
164
hideScrollBar(uint16_t scrollBarID)165 void hideScrollBar(uint16_t scrollBarID)
166 {
167 assert(scrollBarID < NUM_SCROLLBARS);
168 scrollBars[scrollBarID].state = 0;
169 scrollBars[scrollBarID].visible = false;
170 }
171
setScrollBarThumbCoords(uint16_t scrollBarID)172 static void setScrollBarThumbCoords(uint16_t scrollBarID)
173 {
174 int16_t thumbX, thumbY, thumbW, thumbH, scrollEnd, realThumbLength;
175 int32_t tmp32, length, end;
176 double dTmp;
177
178 assert(scrollBarID < NUM_SCROLLBARS);
179 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
180
181 assert(scrollBar->page > 0);
182
183 // uninitialized scrollbar, set full thumb length/height
184 if (scrollBar->end == 0)
185 {
186 scrollBar->thumbX = scrollBar->x + 1;
187 scrollBar->thumbY = scrollBar->y + 1;
188 scrollBar->thumbW = scrollBar->w - 2;
189 scrollBar->thumbH = scrollBar->h - 2;
190 return;
191 }
192
193 if (scrollBar->type == SCROLLBAR_HORIZONTAL)
194 {
195 // horizontal scrollbar
196
197 thumbY = scrollBar->y + 1;
198 thumbH = scrollBar->h - 2;
199 scrollEnd = scrollBar->x + scrollBar->w;
200
201 if (scrollBar->thumbType == SCROLLBAR_THUMB_NOFLAT)
202 {
203 realThumbLength = 15;
204
205 thumbW = realThumbLength;
206 if (thumbW < MIN_THUMB_LENGTH)
207 thumbW = MIN_THUMB_LENGTH;
208
209 if (scrollBar->end > 0)
210 {
211 length = scrollBar->w - realThumbLength;
212 dTmp = (length / (double)scrollBar->end) * scrollBar->pos;
213 tmp32 = (int32_t)(dTmp + 0.5);
214 thumbX = (int16_t)(scrollBar->x + tmp32);
215 }
216 else
217 {
218 thumbX = scrollBar->x;
219 }
220 }
221 else
222 {
223 if (scrollBar->end > 0)
224 {
225 dTmp = (scrollBar->w / (double)scrollBar->end) * scrollBar->page;
226 tmp32 = (int32_t)(dTmp + 0.5);
227 realThumbLength = (int16_t)CLAMP(tmp32, 1, scrollBar->w);
228 }
229 else
230 {
231 realThumbLength = 1;
232 }
233
234 thumbW = realThumbLength;
235 if (thumbW < MIN_THUMB_LENGTH)
236 thumbW = MIN_THUMB_LENGTH;
237
238 if (scrollBar->end > scrollBar->page)
239 {
240 length = scrollBar->w - thumbW;
241 end = scrollBar->end - scrollBar->page;
242
243 dTmp = (length / (double)end) * scrollBar->pos;
244 tmp32 = (int32_t)(dTmp + 0.5);
245 thumbX = (int16_t)(scrollBar->x + tmp32);
246 }
247 else
248 {
249 thumbX = scrollBar->x;
250 }
251 }
252
253 // prevent scrollbar thumb coords from being outside of the scrollbar area
254 thumbX = CLAMP(thumbX, scrollBar->x, scrollEnd-1);
255 if (thumbX+thumbW > scrollEnd)
256 thumbW = scrollEnd - thumbX;
257 }
258 else
259 {
260 // vertical scrollbar
261
262 thumbX = scrollBar->x + 1;
263 thumbW = scrollBar->w - 2;
264 scrollEnd = scrollBar->y + scrollBar->h;
265
266 if (scrollBar->end > 0)
267 {
268 dTmp = (scrollBar->h / (double)scrollBar->end) * scrollBar->page;
269 tmp32 = (int32_t)(dTmp + 0.5);
270 realThumbLength = (int16_t)CLAMP(tmp32, 1, scrollBar->h);
271 }
272 else
273 {
274 realThumbLength = 1;
275 }
276
277 thumbH = realThumbLength;
278 if (thumbH < MIN_THUMB_LENGTH)
279 thumbH = MIN_THUMB_LENGTH;
280
281 if (scrollBar->end > scrollBar->page)
282 {
283 length = scrollBar->h - thumbH;
284 end = scrollBar->end - scrollBar->page;
285
286 dTmp = (length / (double)end) * scrollBar->pos;
287 tmp32 = (int32_t)(dTmp + 0.5);
288 thumbY = (int16_t)(scrollBar->y + tmp32);
289 }
290 else
291 {
292 thumbY = scrollBar->y;
293 }
294
295 // prevent scrollbar thumb coords from being outside of the scrollbar area
296 thumbY = CLAMP(thumbY, scrollBar->y, scrollEnd - 1);
297 if (thumbY+thumbH > scrollEnd)
298 thumbH = scrollEnd - thumbY;
299 }
300
301 // set values now
302 scrollBar->realThumbLength = realThumbLength;
303 scrollBar->thumbX = thumbX;
304 scrollBar->thumbY = thumbY;
305 scrollBar->thumbW = thumbW;
306 scrollBar->thumbH = thumbH;
307 }
308
scrollBarScrollUp(uint16_t scrollBarID,uint32_t amount)309 void scrollBarScrollUp(uint16_t scrollBarID, uint32_t amount)
310 {
311 assert(scrollBarID < NUM_SCROLLBARS);
312 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
313
314 assert(scrollBar->page > 0 && scrollBar->end > 0);
315
316 if (scrollBar->end < scrollBar->page || scrollBar->pos == 0)
317 return;
318
319 if (scrollBar->pos >= amount)
320 scrollBar->pos -= amount;
321 else
322 scrollBar->pos = 0;
323
324 setScrollBarThumbCoords(scrollBarID);
325 drawScrollBar(scrollBarID);
326
327 if (scrollBar->callbackFunc != NULL)
328 scrollBar->callbackFunc(scrollBar->pos);
329 }
330
scrollBarScrollDown(uint16_t scrollBarID,uint32_t amount)331 void scrollBarScrollDown(uint16_t scrollBarID, uint32_t amount)
332 {
333 assert(scrollBarID < NUM_SCROLLBARS);
334 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
335
336 assert(scrollBar->page > 0 && scrollBar->end > 0);
337
338 if (scrollBar->end < scrollBar->page)
339 return;
340
341 uint32_t endPos = scrollBar->end;
342 if (scrollBar->thumbType == SCROLLBAR_THUMB_FLAT)
343 {
344 if (endPos >= scrollBar->page)
345 endPos -= scrollBar->page;
346 else
347 endPos = 0;
348 }
349
350 // check if we're already at the end
351 if (scrollBar->pos == endPos)
352 return;
353
354 scrollBar->pos += amount;
355 if (scrollBar->pos > endPos)
356 scrollBar->pos = endPos;
357
358 setScrollBarThumbCoords(scrollBarID);
359 drawScrollBar(scrollBarID);
360
361 if (scrollBar->callbackFunc != NULL)
362 scrollBar->callbackFunc(scrollBar->pos);
363 }
364
scrollBarScrollLeft(uint16_t scrollBarID,uint32_t amount)365 void scrollBarScrollLeft(uint16_t scrollBarID, uint32_t amount)
366 {
367 scrollBarScrollUp(scrollBarID, amount);
368 }
369
scrollBarScrollRight(uint16_t scrollBarID,uint32_t amount)370 void scrollBarScrollRight(uint16_t scrollBarID, uint32_t amount)
371 {
372 scrollBarScrollDown(scrollBarID, amount);
373 }
374
setScrollBarPos(uint16_t scrollBarID,uint32_t pos,bool triggerCallBack)375 void setScrollBarPos(uint16_t scrollBarID, uint32_t pos, bool triggerCallBack)
376 {
377 assert(scrollBarID < NUM_SCROLLBARS);
378 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
379
380 if (scrollBar->page == 0)
381 {
382 scrollBar->pos = 0;
383 return;
384 }
385
386 if (scrollBar->end < scrollBar->page || scrollBar->pos == pos)
387 {
388 setScrollBarThumbCoords(scrollBarID);
389 drawScrollBar(scrollBarID);
390 return;
391 }
392
393 uint32_t endPos = scrollBar->end;
394 if (scrollBar->thumbType == SCROLLBAR_THUMB_FLAT)
395 {
396 if (endPos >= scrollBar->page)
397 endPos -= scrollBar->page;
398 else
399 endPos = 0;
400 }
401
402 scrollBar->pos = pos;
403 if (scrollBar->pos > endPos)
404 scrollBar->pos = endPos;
405
406 setScrollBarThumbCoords(scrollBarID);
407 drawScrollBar(scrollBarID);
408
409 if (triggerCallBack && scrollBar->callbackFunc != NULL)
410 scrollBar->callbackFunc(scrollBar->pos);
411 }
412
getScrollBarPos(uint16_t scrollBarID)413 uint32_t getScrollBarPos(uint16_t scrollBarID)
414 {
415 assert(scrollBarID < NUM_SCROLLBARS);
416 return scrollBars[scrollBarID].pos;
417 }
418
setScrollBarEnd(uint16_t scrollBarID,uint32_t end)419 void setScrollBarEnd(uint16_t scrollBarID, uint32_t end)
420 {
421 assert(scrollBarID < NUM_SCROLLBARS);
422 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
423
424 if (end < 1)
425 end = 1;
426
427 scrollBar->end = end;
428
429 bool setPos = false;
430 if (scrollBar->pos >= end)
431 {
432 scrollBar->pos = end - 1;
433 setPos = true;
434 }
435
436 if (scrollBar->page > 0)
437 {
438 if (setPos)
439 {
440 setScrollBarPos(scrollBarID, scrollBar->pos, false);
441 // this will also call setScrollBarThumbCoords() and drawScrollBar()
442 }
443 else
444 {
445 setScrollBarThumbCoords(scrollBarID);
446 drawScrollBar(scrollBarID);
447 }
448 }
449 }
450
setScrollBarPageLength(uint16_t scrollBarID,uint32_t pageLength)451 void setScrollBarPageLength(uint16_t scrollBarID, uint32_t pageLength)
452 {
453 assert(scrollBarID < NUM_SCROLLBARS);
454 scrollBar_t *scrollBar = &scrollBars[scrollBarID];
455
456 if (pageLength < 1)
457 pageLength = 1;
458
459 scrollBar->page = pageLength;
460 if (scrollBar->end > 0)
461 {
462 setScrollBarPos(scrollBarID, scrollBar->pos, false);
463 setScrollBarThumbCoords(scrollBarID);
464 drawScrollBar(scrollBarID);
465 }
466 }
467
testScrollBarMouseDown(void)468 bool testScrollBarMouseDown(void)
469 {
470 uint16_t start, end;
471 int32_t scrollPos, length;
472 double dTmp;
473
474 if (ui.sysReqShown)
475 {
476 // if a system request is open, only test the first three scrollbars (reserved)
477 start = 0;
478 end = 3;
479 }
480 else
481 {
482 start = 3;
483 end = NUM_SCROLLBARS;
484 }
485
486 const int32_t mx = mouse.x;
487 const int32_t my = mouse.y;
488
489 scrollBar_t *scrollBar = &scrollBars[start];
490 for (uint16_t i = start; i < end; i++, scrollBar++)
491 {
492 if (!scrollBar->visible)
493 continue;
494
495 if (mx >= scrollBar->x && mx < scrollBar->x+scrollBar->w &&
496 my >= scrollBar->y && my < scrollBar->y+scrollBar->h)
497 {
498 mouse.lastUsedObjectID = i;
499 mouse.lastUsedObjectType = OBJECT_SCROLLBAR;
500
501 // kludge for when a system request is about to open
502 scrollBar->state = SCROLLBAR_PRESSED;
503 if (scrollBar->thumbType == SCROLLBAR_THUMB_NOFLAT)
504 drawScrollBar(mouse.lastUsedObjectType);
505
506 if (scrollBar->type == SCROLLBAR_HORIZONTAL)
507 {
508 mouse.lastScrollXTmp = mouse.lastScrollX = mx;
509
510 if (mx >= scrollBar->thumbX && mx < scrollBar->thumbX+scrollBar->thumbW)
511 {
512 mouse.saveMouseX = mouse.lastScrollX - scrollBar->thumbX;
513 }
514 else
515 {
516 mouse.saveMouseX = scrollBar->thumbW >> 1;
517
518 scrollPos = mouse.lastScrollX - scrollBar->x - mouse.saveMouseX;
519 if (scrollBar->thumbType == SCROLLBAR_THUMB_NOFLAT)
520 {
521 dTmp = scrollPos * (scrollBar->w / (double)(scrollBar->w - scrollBar->thumbW));
522 scrollPos = (int32_t)(dTmp + 0.5);
523 }
524
525 assert(scrollBar->w > 0);
526 scrollPos = CLAMP(scrollPos, 0, scrollBar->w);
527
528 length = scrollBar->w + (scrollBar->realThumbLength - scrollBar->thumbW);
529 if (length < 1)
530 length = 1;
531
532 dTmp = ((double)scrollPos * scrollBar->end) / length;
533 scrollPos = (int32_t)(dTmp + 0.5);
534
535 setScrollBarPos(mouse.lastUsedObjectID, scrollPos, true);
536 }
537 }
538 else
539 {
540 mouse.lastScrollY = my;
541 if (my >= scrollBar->thumbY && my < scrollBar->thumbY+scrollBar->thumbH)
542 {
543 mouse.saveMouseY = mouse.lastScrollY - scrollBar->thumbY;
544 }
545 else
546 {
547 mouse.saveMouseY = scrollBar->thumbH >> 1;
548
549 scrollPos = mouse.lastScrollY - scrollBar->y - mouse.saveMouseY;
550
551 assert(scrollBar->h > 0);
552 scrollPos = CLAMP(scrollPos, 0, scrollBar->h);
553
554 length = scrollBar->h + (scrollBar->realThumbLength - scrollBar->thumbH);
555 if (length < 1)
556 length = 1;
557
558 dTmp = ((double)scrollPos * scrollBar->end) / length;
559 scrollPos = (int32_t)(dTmp + 0.5);
560
561 setScrollBarPos(mouse.lastUsedObjectID, scrollPos, true);
562 }
563 }
564
565 // objectID can be set to none in scrollbar's callback during setScrollBarPos()
566 if (mouse.lastUsedObjectID == OBJECT_ID_NONE)
567 return true;
568
569 scrollBar->state = SCROLLBAR_PRESSED;
570 if (scrollBar->thumbType == SCROLLBAR_THUMB_NOFLAT)
571 drawScrollBar(mouse.lastUsedObjectID);
572
573 return true;
574 }
575 }
576
577 return false;
578 }
579
testScrollBarMouseRelease(void)580 void testScrollBarMouseRelease(void)
581 {
582 if (mouse.lastUsedObjectType != OBJECT_SCROLLBAR || mouse.lastUsedObjectID == OBJECT_ID_NONE)
583 return;
584
585 assert(mouse.lastUsedObjectID < NUM_SCROLLBARS);
586 scrollBar_t *scrollBar = &scrollBars[mouse.lastUsedObjectID];
587
588 if (scrollBar->visible)
589 {
590 scrollBar->state = SCROLLBAR_UNPRESSED;
591 drawScrollBar(mouse.lastUsedObjectID);
592 }
593 }
594
handleScrollBarsWhileMouseDown(void)595 void handleScrollBarsWhileMouseDown(void)
596 {
597 int32_t scrollX, scrollY, length;
598 double dTmp;
599
600 assert(mouse.lastUsedObjectID >= 0 && mouse.lastUsedObjectID < NUM_SCROLLBARS);
601 scrollBar_t *scrollBar = &scrollBars[mouse.lastUsedObjectID];
602 if (!scrollBar->visible)
603 return;
604
605 if (scrollBar->type == SCROLLBAR_HORIZONTAL)
606 {
607 if (mouse.x != mouse.lastScrollX)
608 {
609 mouse.lastScrollX = mouse.x;
610 scrollX = mouse.lastScrollX - mouse.saveMouseX - scrollBar->x;
611
612 if (scrollBar->thumbType == SCROLLBAR_THUMB_NOFLAT)
613 {
614 assert(scrollBar->w >= 16);
615 dTmp = scrollX * (scrollBar->w / (double)(scrollBar->w - scrollBar->thumbW));
616 scrollX = (int32_t)(dTmp + 0.5);
617 }
618
619 assert(scrollBar->w > 0);
620 scrollX = CLAMP(scrollX, 0, scrollBar->w);
621
622 length = scrollBar->w + (scrollBar->realThumbLength - scrollBar->thumbW);
623 if (length < 1)
624 length = 1;
625
626 dTmp = ((double)scrollX * scrollBar->end) / length;
627 scrollX = (int32_t)(dTmp + 0.5);
628
629 setScrollBarPos(mouse.lastUsedObjectID, scrollX, true);
630
631 if (mouse.lastUsedObjectID != OBJECT_ID_NONE) // this can change in the callback in setScrollBarPos()
632 drawScrollBar(mouse.lastUsedObjectID);
633 }
634 }
635 else
636 {
637 if (mouse.y != mouse.lastScrollY)
638 {
639 mouse.lastScrollY = mouse.y;
640
641 scrollY = mouse.lastScrollY - mouse.saveMouseY - scrollBar->y;
642
643 assert(scrollBar->h > 0);
644 scrollY = CLAMP(scrollY, 0, scrollBar->h);
645
646 length = scrollBar->h + (scrollBar->realThumbLength - scrollBar->thumbH);
647 if (length < 1)
648 length = 1;
649
650 dTmp = ((double)scrollY * scrollBar->end) / length;
651 scrollY = (int32_t)(dTmp + 0.5);
652
653 setScrollBarPos(mouse.lastUsedObjectID, scrollY, true);
654
655 if (mouse.lastUsedObjectID != OBJECT_ID_NONE) // this can change in the callback in setScrollBarPos()
656 drawScrollBar(mouse.lastUsedObjectID);
657 }
658 }
659 }
660
initializeScrollBars(void)661 void initializeScrollBars(void)
662 {
663 // pattern editor
664 setScrollBarPageLength(SB_CHAN_SCROLL, 8);
665 setScrollBarEnd(SB_CHAN_SCROLL, 8);
666
667 // position editor
668 setScrollBarPageLength(SB_POS_ED, 5);
669 setScrollBarEnd(SB_POS_ED, 5);
670
671 // instrument switcher
672 setScrollBarPageLength(SB_SAMPLE_LIST, 5);
673 setScrollBarEnd(SB_SAMPLE_LIST, 16);
674
675 // help screen
676 setScrollBarPageLength(SB_HELP_SCROLL, 15);
677 setScrollBarEnd(SB_HELP_SCROLL, 1);
678
679 // config screen
680 setScrollBarPageLength(SB_AMP_SCROLL, 1);
681 setScrollBarEnd(SB_AMP_SCROLL, 31);
682 setScrollBarPageLength(SB_MASTERVOL_SCROLL, 1);
683 setScrollBarEnd(SB_MASTERVOL_SCROLL, 256);
684 setScrollBarPageLength(SB_PAL_R, 1);
685 setScrollBarEnd(SB_PAL_R, 63);
686 setScrollBarPageLength(SB_PAL_G, 1);
687 setScrollBarEnd(SB_PAL_G, 63);
688 setScrollBarPageLength(SB_PAL_B, 1);
689 setScrollBarEnd(SB_PAL_B, 63);
690 setScrollBarPageLength(SB_PAL_CONTRAST, 1);
691 setScrollBarEnd(SB_PAL_CONTRAST, 100);
692 setScrollBarPageLength(SB_MIDI_SENS, 1);
693 setScrollBarEnd(SB_MIDI_SENS, 200);
694 setScrollBarPageLength(SB_AUDIO_OUTPUT_SCROLL, 6);
695 setScrollBarEnd(SB_AUDIO_OUTPUT_SCROLL, 1);
696 setScrollBarPageLength(SB_AUDIO_INPUT_SCROLL, 4);
697 setScrollBarEnd(SB_AUDIO_INPUT_SCROLL, 1);
698
699 #ifdef HAS_MIDI
700 setScrollBarPageLength(SB_MIDI_INPUT_SCROLL, 15);
701 setScrollBarEnd(SB_MIDI_INPUT_SCROLL, 1);
702 #endif
703
704 // disk op.
705 setScrollBarPageLength(SB_DISKOP_LIST, DISKOP_ENTRY_NUM);
706 setScrollBarEnd(SB_DISKOP_LIST, 1);
707
708 // instrument editor
709 setScrollBarPageLength(SB_INST_VOL, 1);
710 setScrollBarEnd(SB_INST_VOL, 64);
711 setScrollBarPageLength(SB_INST_PAN, 1);
712 setScrollBarEnd(SB_INST_PAN, 255);
713 setScrollBarPageLength(SB_INST_FTUNE, 1);
714 setScrollBarEnd(SB_INST_FTUNE, 255);
715 setScrollBarPageLength(SB_INST_FADEOUT, 1);
716 setScrollBarEnd(SB_INST_FADEOUT, 0xFFF);
717 setScrollBarPageLength(SB_INST_VIBSPEED, 1);
718 setScrollBarEnd(SB_INST_VIBSPEED, 0x3F);
719 setScrollBarPageLength(SB_INST_VIBDEPTH, 1);
720 setScrollBarEnd(SB_INST_VIBDEPTH, 0xF);
721 setScrollBarPageLength(SB_INST_VIBSWEEP, 1);
722 setScrollBarEnd(SB_INST_VIBSWEEP, 0xFF);
723
724 // instrument editor extension
725 setScrollBarPageLength(SB_INST_EXT_MIDI_CH, 1);
726 setScrollBarEnd(SB_INST_EXT_MIDI_CH, 15);
727 setScrollBarPageLength(SB_INST_EXT_MIDI_PRG, 1);
728 setScrollBarEnd(SB_INST_EXT_MIDI_PRG, 127);
729 setScrollBarPageLength(SB_INST_EXT_MIDI_BEND, 1);
730 setScrollBarEnd(SB_INST_EXT_MIDI_BEND, 36);
731 }
732