1 /*
2 ** Abandon all hope all ye who enter here
3 ** (consider this fair warning)
4 */
5 
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <stddef.h>
10 
11 #include <system_includes.h>
12 
13 #include "replay.h"
14 #include "gui.h"
15 #include "util.h"
16 #include "about.h"
17 #include "undo.h"
18 #ifdef __APPLE__
19 char *osxGetPrefsPath();
20 char *osxGetResourcesPath(char *, const char*);
21 #endif
22 
23 #ifndef __SDL_WRAPPER__
24 struct Library *IntuitionBase = NULL;
25 struct Library *P96Base       = NULL;
26 struct Library *GfxBase       = NULL;
27 struct Library *DataTypesBase = NULL;
28 struct Library *DiskfontBase  = NULL;
29 struct Library *AslBase       = NULL;
30 struct Library *KeymapBase    = NULL;
31 struct Library *RequesterBase = NULL;
32 
33 struct IntuitionIFace *IIntuition = NULL;
34 struct P96IFace       *IP96       = NULL;
35 struct GraphicsIFace  *IGraphics  = NULL;
36 struct DataTypesIFace *IDataTypes = NULL;
37 struct DiskfontIFace  *IDiskfont  = NULL;
38 struct AslIFace       *IAsl       = NULL;
39 struct KeymapIFace    *IKeymap    = NULL;
40 struct RequesterIFace *IRequester = NULL;
41 
42 struct InputEvent iev;
43 
44 struct Window *mainwin = NULL;
45 struct Window *prefwin = NULL;
46 struct Screen *scr = NULL;
47 
48 struct Gadget gad_drag;
49 struct Gadget gad_drag2;
50 struct Gadget gad_depth;
51 #else
52 struct SDL_Surface *ssrf = NULL;
53 BOOL needaflip = FALSE;
54 extern int srfdepth;
55 extern SDL_Event event;
56 extern int16 rp_audiobuffer[];
57 extern uint32 rp_audiobuflen;
58 extern BOOL aboutwin_open;
59 #endif
60 
61 BOOL gui_savethem;
62 
63 #ifndef __SDL_WRAPPER__
64 int32  gui_tick_signum = -1;
65 uint32 gui_tick_sig = 0;
66 
67 uint32 mainwin_sig = 0;
68 uint32 prefwin_sig = 0;
69 uint32 gui_sigs    = 0;
70 extern int8   *rp_audiobuffer[];
71 #endif
72 
73 int16 pw_x = -1, pw_y = -1;
74 int16 pw_bl = 0, pw_bt = 0;
75 
76 int32  basekey = 24;
77 
78 uint8  *cbpbuf = NULL;
79 uint32  cbpblen = 0;
80 uint16  cbplcol = 0;
81 uint16  cbprcol = 0;
82 uint16  cbpchns = 0;
83 uint16  cbprows = 0;
84 
85 extern uint32  rp_audiobuflen;
86 
87 #define TRACKED_X 3
88 #define TRACKED_Y 324
89 #define TRACKED_W 740
90 #define TRACKED_H 272
91 #define TRACKED_MX (TRACKED_W-1)
92 #define TRACKED_MY (TRACKED_H-1)
93 
94 #define POSED_X 298
95 #define POSED_Y 190
96 #define POSED_W 316
97 #define POSED_H 98
98 #define POSED_MX (POSED_W-1)
99 #define POSED_MY (POSED_H-1)
100 
101 #define INSLIST_X 622
102 #define INSLIST_Y 152
103 #define INSLIST_W 168
104 #define INSLIST_H 136
105 #define INSLIST_MX (INSLIST_W-1)
106 #define INSLIST_MY (INSLIST_H-1)
107 
108 #define PERF_X 291
109 #define PERF_Y 144
110 #define PERF_W 146
111 #define PERF_H 438
112 #define PERF_MX (PERF_W-1)
113 #define PERF_MY (PERF_H-1)
114 
115 #define INSLSTB_X 474
116 #define INSLSTB_Y 144
117 #define INSLSTB_W 168
118 #define INSLSTB_H 438
119 #define INSLSTB_MX (INSLSTB_W-1)
120 #define INSLSTB_MY (INSLSTB_H-1)
121 
122 int32 qual;
123 BOOL qualRMB = FALSE;
124 
125 //BOOL qualShift=FALSE, qualCtrl=FALSE, qualRMB=FALSE, qualAlt, qualAmiga;
126 
127 extern struct List *rp_tunelist;
128 extern struct SignalSemaphore *rp_list_ss;
129 
130 struct ahx_tune *curtune = NULL;
131 extern struct ahx_tune *rp_curtune;
132 
133 struct ahx_instrument *perf_lastinst = NULL;
134 int32 perf_laststep = -1;
135 int32 perf_lastcx = -1;
136 int32 perf_lastcy = -1;
137 int32 perf_lastplen = -1;
138 
139 struct ahx_tune *tmr_lasttune = NULL;
140 uint32 tmr_lasttime = 0;
141 
142 int32 vum_last[MAX_CHANNELS];
143 BOOL vum_needclr = 0;
144 int32 wm_count = 0;
145 
146 int32 pref_defstereo  = 4;
147 int32 pref_maxundobuf = 2;
148 BOOL  pref_fullscr    = FALSE;
149 BOOL  pref_blankzeros = FALSE;
150 
151 BOOL  pref_dorestart = FALSE;
152 BOOL  pref_oldfullscr;
153 TEXT  pref_oldskindir[512];
154 #ifdef __SDL_WRAPPER__
155 BOOL  pref_rctrlplaypos = FALSE;
156 #endif
157 
158 BOOL fullscr = FALSE;
159 
160 extern BOOL quitting;
161 
162 enum
163 {
164   PAL_BACK = 0,
165   PAL_BARDARK,
166   PAL_BARMID,
167   PAL_BARLIGHT,
168   PAL_TEXT,
169   PAL_DISABLEDTEXT,
170   PAL_WAVEMETER,
171   PAL_CURSNORM,
172   PAL_CURSEDIT,
173   PAL_BTNTEXT,
174   PAL_BTNSHADOW,
175   PAL_FKEYHIGHLIGHT,
176   PAL_POSEDCHIND,
177   PAL_TABTEXT,
178   PAL_TABSHADOW,
179   PAL_END
180 };
181 
182 uint32 pal[] = { 0x000000, 0x500000, 0x780000, 0xff5555, 0xffffff, 0x808080, 0xff88ff, 0xffffff, 0xffff88, 0xffffff, 0x000000, 0xffffff, 0xffffff, 0xffffff, 0x000000 };
183 #ifdef __SDL_WRAPPER__
184 uint32 mappal[sizeof(pal)/sizeof(uint32)];
185 #endif
186 
187 const TEXT *notenames[] = { "---",
188   "C-1", "C#1", "D-1", "D#1", "E-1", "F-1", "F#1", "G-1", "G#1", "A-1", "A#1", "B-1",
189   "C-2", "C#2", "D-2", "D#2", "E-2", "F-2", "F#2", "G-2", "G#2", "A-2", "A#2", "B-2",
190   "C-3", "C#3", "D-3", "D#3", "E-3", "F-3", "F#3", "G-3", "G#3", "A-3", "A#3", "B-3",
191   "C-4", "C#4", "D-4", "D#4", "E-4", "F-4", "F#4", "G-4", "G#4", "A-4", "A#4", "B-4",
192   "C-5", "C#5", "D-5", "D#5", "E-5", "F-5", "F#5", "G-5", "G#5", "A-5", "A#5", "B-5" };
193 
194 const int32 posed_xoff[] = {  4*7,  5*7,  6*7,   8*7,  9*7,
195                        11*7, 12*7, 13*7,  15*7, 16*7,
196                        18*7, 19*7, 20*7,  22*7, 23*7,
197 
198                        25*7, 26*7, 27*7,  29*7, 30*7,
199                        32*7, 33*7, 34*7,  36*7, 37*7,
200                        39*7, 40*7, 41*7,  43*7, 44*7 };
201 
202 const int32 tracked_xoff[] = {  3*8,   7*8,  8*8,  10*8, 11*8, 12*8,  14*8, 15*8, 16*8,
203                          18*8,  22*8, 23*8,  25*8, 26*8, 27*8,  29*8, 30*8, 31*8,
204                          33*8,  37*8, 38*8,  40*8, 41*8, 42*8,  44*8, 45*8, 46*8,
205 
206                          48*8,  52*8, 53*8,  55*8, 56*8, 57*8,  59*8, 60*8, 61*8,
207                          63*8,  67*8, 68*8,  70*8, 71*8, 72*8,  74*8, 75*8, 76*8,
208                          78*8,  82*8, 83*8,  85*8, 86*8, 87*8,  89*8, 90*8, 91*8 };
209 
210 const int32 perf_xoff[] = { 4*8, 9*8, 11*8, 12*8, 13*8, 15*8, 16*8, 17*8 };
211 
212 struct czone
213 {
214   int16 x;
215   int16 y;
216   int16 w;
217   int16 h;
218 };
219 
220 #define NBB_ENABLED 0
221 #define NBF_ENABLED (1L<<NBB_ENABLED)
222 #define NBB_WAVELEN 1
223 #define NBF_WAVELEN (1L<<NBB_WAVELEN)
224 #define NBB_UDDURINGPLAY 2
225 #define NBF_UDDURINGPLAY (1L<<NBB_UDDURINGPLAY)
226 #define NBB_ONOFF 3
227 #define NBF_ONOFF (1L<<NBB_ONOFF)
228 
229 struct numberbox
230 {
231   int16  x, y;
232   int16  w, h;
233   TEXT   fmt[8];
234   int32  max, min;
235   int32  cnum;
236   uint16 flags;
237   int16  pressed;
238 };
239 
240 
241 #define TBB_ENABLED 0
242 #define TBF_ENABLED (1L<<TBB_ENABLED)
243 #define TBB_ACTIVE 1
244 #define TBF_ACTIVE (1L<<TBB_ACTIVE)
245 #define TBB_VISIBLE 2
246 #define TBF_VISIBLE (1L<<TBB_VISIBLE)
247 
248 struct prefcycle
249 {
250   int16   x, y;
251   int32   copt;
252   int32   numopts;
253   int32   zone;
254   TEXT  **options;
255 };
256 
257 struct popup
258 {
259   int16  x, y;
260 };
261 
262 enum
263 {
264   NB_POSNR = 0,
265   NB_LENGTH,
266   NB_RESPOS,
267   NB_TRKLEN,
268   NB_SSNR,
269   NB_CURSS,
270   NB_SSPOS,
271   NB_CHANS,
272   NB_MIXG,
273   NB_SPEEDMULT,
274   NB_DRUMPADMODE,
275   NB_END
276 };
277 
278 enum
279 {
280   INB_INS = 0,
281   INB_VOL,
282   INB_WAVELEN,
283   INB_ATTACK,
284   INB_AVOL,
285   INB_DECAY,
286   INB_DVOL,
287   INB_SUSTAIN,
288   INB_RELEASE,
289   INB_RVOL,
290   INB_VIBDELAY,
291   INB_VIBDEPTH,
292   INB_VIBSPEED,
293   INB_SQRLOWER,
294   INB_SQRUPPER,
295   INB_SQRSPEED,
296   INB_FLTLOWER,
297   INB_FLTUPPER,
298   INB_FLTSPEED,
299   INB_PERFSPEED,
300   INB_PERFLEN,
301   INB_HARDCUT,
302   INB_RELCUT,
303   INB_END
304 };
305 
306 enum
307 {
308   BBA_NOTHING = 0,
309   BBA_PLAYPOS,
310   BBA_PLAYSONG,
311   BBA_STOP,
312   BBA_ZAP,
313   BBA_NEWTAB,
314   BBA_CLONETAB,
315   BBA_LOADTUNE,
316   BBA_SAVEAHX,
317   BBA_SAVEHVL,
318   BBA_LOADINS,
319   BBA_SAVEINS,
320   BBA_CONTSONG,
321   BBA_CONTPOS,
322   BBA_INSEDIT,
323   BBA_PREFS,
324   BBA_AUTOGAIN,
325   BBA_ABOUT,
326 
327   BBA_CUTTRK,
328   BBA_COPYTRK,
329   BBA_PASTE,
330   BBA_PASTECMDS,
331   BBA_NOTEUP,
332   BBA_NOTEDN,
333   BBA_SCRLUP,
334   BBA_SCRLDN,
335   BBA_REVERSE,
336 
337   BBA_UNDO,
338   BBA_REDO,
339 
340   BBA_OPTIMISE,
341   BBA_OPTIMISE_MORE,
342 
343   BBA_ZAP_SONG,
344   BBA_ZAP_TRACKS,
345   BBA_ZAP_POSNS,
346   BBA_ZAP_INSTRS,
347   BBA_ZAP_ALL,
348   BBA_BACK,
349 
350   BBA_END
351 };
352 
353 enum
354 {
355   PTB_SONGDIR = 0,
356   PTB_INSTDIR,
357   PTB_SKINDIR,
358   PTB_END
359 };
360 
361 enum
362 {
363   PP_SONGDIR = 0,
364   PP_INSTDIR,
365   PP_SKINDIR,
366   PP_END
367 };
368 
369 struct buttonbank
370 {
371   int16  x, y;
372   int32  zone;
373   TEXT  *name;
374   int32  action;
375   int32  raction;
376   int32  xo;
377 };
378 
379 enum
380 {
381   BM_LOGO = 0,
382   BM_TAB_AREA,
383   BM_TAB_LEFT,
384   BM_TAB_MID,
385   BM_TAB_RIGHT,
386   BM_TAB_TEXT,
387   BM_ITAB_LEFT,
388   BM_ITAB_MID,
389   BM_ITAB_RIGHT,
390   BM_ITAB_TEXT,
391   BM_BUTBANKR,
392   BM_BUTBANKP,
393   BM_BG_TRACKER,
394   BM_BG_INSED,
395   BM_PLUSMINUS,
396   BM_POSED,
397   BM_TRACKED,
398   BM_TRACKBAR,
399   BM_PERF,
400   BM_VUMETER,
401   BM_WAVEMETERS,
402   BM_DEPTH,
403   BM_PRF_BG,
404   BM_PRF_CYCLE,
405   BM_INSLIST,
406   BM_INSLISTB,
407   BM_TRKBANKR,
408   BM_TRKBANKP,
409   BM_CHANMUTE,
410   BM_BLANK,
411   BM_DIRPOPUP,
412   BM_END
413 };
414 
415 enum
416 {
417   PC_WMODE = 0,
418   PC_DEFSTEREO,
419   PC_BLANKZERO,
420   PC_MAXUNDOBUF,
421   PC_END
422 };
423 
424 struct tunetab
425 {
426   struct ahx_tune *tune;
427   int32            zone;
428 };
429 
430 TEXT fixfontname[256];
431 TEXT sfxfontname[256];
432 TEXT prpfontname[256];
433 
434 TEXT skinext[32];
435 
436 BOOL tabtextback = FALSE;
437 BOOL tabtextshad = TRUE;
438 BOOL posedadvance = TRUE;
439 int32 defnotejump = 1, definotejump = 1;
440 
441 #ifndef __SDL_WRAPPER__
442 struct TextAttr fixfontattr = { fixfontname, 16, 0, 0 };
443 struct TextAttr sfxfontattr = { sfxfontname, 14, 0, 0 };
444 struct TextAttr prpfontattr = { prpfontname, 16, 0, 0 };
445 
446 struct TextFont *fixfont = NULL;
447 struct TextFont *sfxfont = NULL;
448 struct TextFont *prpfont = NULL;
449 #else
450 TTF_Font *fixttf = NULL;
451 TTF_Font *sfxttf = NULL;
452 TTF_Font *prpttf = NULL;
453 BOOL prefwin_open = FALSE;
454 #endif
455 
456 #define MAX_ZONES 100
457 #define MAX_PZONES 20
458 
459 int32 last_tbox = -1;
460 
461 struct rawbm      mainbm, prefbm;
462 struct rawbm      bitmaps[BM_END];
463 struct czone      zones[MAX_ZONES], pzones[MAX_PZONES];
464 struct numberbox  trk_nb[NB_END], ins_nb[INB_END];
465 struct textbox    tbx[TB_END], ptb[PTB_END];
466 struct textbox   *etbx = NULL, *ptbx = NULL;
467 struct popup      pp[PP_END];
468 struct tunetab    ttab[8];
469 struct buttonbank bbank[16];
470 struct buttonbank tbank[12];
471 struct prefcycle  pcyc[PC_END];
472 
473 TEXT *pc_wmode_opts[] = { "Windowed", "Fullscreen", NULL };
474 TEXT *pc_defst_opts[] = { "0% (mono)", "25%", "50%", "75%", "100% (paula)", NULL };
475 TEXT *pc_bzero_opts[] = { "No", "Yes", NULL };
476 TEXT *pc_mundo_opts[] = { "Unlimited", "256Kb", "512Kb", "1Mb", "2Mb", "4Mb", NULL };
477 
478 struct ahx_tune *posed_lasttune  = NULL;
479 int16            posed_lastposnr = 1000;
480 int16            posed_lastlchan = 0;
481 int16            posed_lastchans = 0;
482 
483 struct ahx_tune *trked_lasttune   = NULL;
484 int16            trked_lastposnr  = 1000;
485 int16            trked_lastnotenr = 65;
486 int16            trked_lastchans  = 4;
487 int16            trked_lastlchan  = 0;
488 
489 struct ahx_tune *insls_lasttune   = NULL;
490 int16            insls_lastcuri   = -1;
491 int16            insls_lasttopi   = -1;
492 
493 struct ahx_tune *inslsb_lasttune   = NULL;
494 int16            inslsb_lastcuri   = -1;
495 int16            inslsb_lasttopi   = -1;
496 
497 int32 numzones = 0;
498 int32 numpzones = 0;
499 int32 cz_lmb, cz_plmb;
500 int32 cz_rmb, cz_prmb;
501 
502 int32 whichcyc = -1;
503 int32 whichpop = -1;
504 
505 int32 zn_close    = -1;
506 int32 zn_scrdep   = -1;
507 int32 zn_mute[6];
508 
509 #ifndef __SDL_WRAPPER__
510 struct FileRequester *ins_lreq;
511 struct FileRequester *ins_sreq;
512 struct FileRequester *sng_lreq;
513 struct FileRequester *sng_sreq;
514 struct FileRequester *dir_req;
515 #endif
516 
517 #define CBB_NOTES 0
518 #define CBF_NOTES (1L<<CBB_NOTES)
519 #define CBB_CMD1 1
520 #define CBF_CMD1 (1L<<CBB_CMD1)
521 #define CBB_CMD2 2
522 #define CBF_CMD2 (1L<<CBB_CMD2)
523 
524 struct ahx_step cb_content[64];
525 int32 cb_contains = 0;
526 int32 cb_length = 0;
527 
528 TEXT songdir[512];
529 TEXT instdir[512];
530 TEXT skindir[512];
531 
532 #ifdef __SDL_WRAPPER__
533 TEXT remsongdir[512];
534 TEXT reminstdir[512];
535 
536 #ifdef WIN32
537 #define PATHSEP '\\'
538 #else
539 #define PATHSEP '/'
540 #endif
541 
setpathpart(char * path,const char * file)542 void setpathpart(char *path, const char *file)
543 {
544   int i;
545 
546   i = strlen(file);
547   while (i>0)
548   {
549     if (file[i] == PATHSEP) break;
550     i--;
551   }
552 
553   if (i>511) return;
554 
555   strcpy(path, file);
556   path[i] = 0;
557 }
558 #endif
559 
isws(TEXT c)560 BOOL isws( TEXT c )
561 {
562   if( ( c == 9 ) || ( c == 32 ) ) return TRUE;
563   return FALSE;
564 }
565 
isnum(TEXT c)566 BOOL isnum( TEXT c )
567 {
568   if( ( c >= '0' ) && ( c <= '9' ) ) return TRUE;
569   return FALSE;
570 }
571 
ishex(TEXT c)572 BOOL ishex( TEXT c )
573 {
574   if( ( c >= '0' ) && ( c <= '9' ) ) return TRUE;
575   if( ( c >= 'A' ) && ( c <= 'F' ) ) return TRUE;
576   if( ( c >= 'a' ) && ( c <= 'f' ) ) return TRUE;
577   return FALSE;
578 }
579 
580 #ifndef __SDL_WRAPPER__
gui_req(uint32 img,const TEXT * title,const TEXT * reqtxt,const TEXT * buttons)581 int32 gui_req( uint32 img, const TEXT *title, const TEXT *reqtxt, const TEXT *buttons )
582 {
583   Object *req_obj;
584   int32 n;
585 
586   req_obj = (Object *)IIntuition->NewObject( IRequester->REQUESTER_GetClass(), NULL,
587     REQ_TitleText,  title,
588     REQ_BodyText,   reqtxt,
589     REQ_GadgetText, buttons,
590     REQ_Image,      img,
591     REQ_WrapBorder, 40,
592     TAG_DONE );
593 
594   if( !req_obj ) return 1;
595 
596   n = IIntuition->IDoMethod( req_obj, RM_OPENREQ, NULL, NULL, scr );
597   IIntuition->DisposeObject( req_obj );
598   return n;
599 }
600 #endif
601 
set_fpen(struct rawbm * bm,int pen)602 void set_fpen(struct rawbm *bm, int pen)
603 {
604   if ((bm->fpenset) && (bm->fpen == pen))
605     return;
606 
607 #ifndef __SDL_WRAPPER__
608   IGraphics->SetRPAttrs( &bm->rp, RPTAG_APenColor, pal[pen]|0xff000000, TAG_DONE );
609 #else
610   bm->fsc.r = pal[pen]>>16;
611   bm->fsc.g = pal[pen]>>8;
612   bm->fsc.b = pal[pen];
613 #endif
614 
615   bm->fpen = pen;
616   bm->fpenset = TRUE;
617 }
618 
set_fcol(struct rawbm * bm,uint32 col)619 void set_fcol(struct rawbm *bm, uint32 col)
620 {
621 #ifndef __SDL_WRAPPER__
622   IGraphics->SetRPAttrs( &bm->rp, RPTAG_APenColor, col|0xff000000, TAG_DONE );
623 #else
624   bm->fsc.r = col>>16;
625   bm->fsc.g = col>>8;
626   bm->fsc.b = col;
627 #endif
628 
629   bm->fpenset = FALSE;
630 }
631 
set_bpen(struct rawbm * bm,int pen)632 void set_bpen(struct rawbm *bm, int pen)
633 {
634   if ((bm->bpenset) && (bm->bpen == pen))
635     return;
636 
637 #ifndef __SDL_WRAPPER__
638   IGraphics->SetRPAttrs( &bm->rp, RPTAG_BPenColor, pal[pen]|0xff000000, TAG_DONE );
639 #else
640   bm->bsc.r = pal[pen]>>16;
641   bm->bsc.g = pal[pen]>>8;
642   bm->bsc.b = pal[pen];
643 #endif
644 
645   bm->bpen = pen;
646   bm->bpenset = TRUE;
647 }
648 
set_pens(struct rawbm * bm,int fpen,int bpen)649 void set_pens(struct rawbm *bm, int fpen, int bpen)
650 {
651   set_fpen(bm, fpen);
652   set_bpen(bm, bpen);
653 }
654 
fillrect_xy(struct rawbm * bm,int x,int y,int x2,int y2)655 void fillrect_xy(struct rawbm *bm, int x, int y, int x2, int y2)
656 {
657 #ifndef __SDL_WRAPPER__
658   IGraphics->RectFill( &bm->rp, x, y, x2, y2 );
659 #else
660   SDL_Rect rect = { .x = x+bm->offx, .y = y+bm->offy, .w = (x2-x)+1, .h = (y2-y)+1 };
661   Uint32 col;
662 
663   if (bm->fpenset)
664     col = mappal[bm->fpen];
665   else
666 #ifdef __APPLE__
667     // Work-around for SDL bug on OSX
668     col = SDL_MapRGB(bm->srf->format, bm->fsc.b, bm->fsc.g, bm->fsc.r) >> 8;
669 #else
670     col = SDL_MapRGB(bm->srf->format, bm->fsc.r, bm->fsc.g, bm->fsc.b);
671 #endif
672   SDL_FillRect(bm->srf, &rect, col);
673 #endif
674 }
675 
bm_to_bm(const struct rawbm * src,int sx,int sy,struct rawbm * dest,int dx,int dy,int w,int h)676 void bm_to_bm(const struct rawbm *src, int sx, int sy, struct rawbm *dest, int dx, int dy, int w, int h)
677 {
678 #ifndef __SDL_WRAPPER__
679   IGraphics->BltBitMapRastPort(src->bm, sx, sy, &dest->rp, dx, dy, w, h, 0x0C0);
680 #else
681   SDL_Rect srect = { .x = sx+src->offx, .y = sy+src->offy, .w = w, .h = h };
682   SDL_Rect drect = { .x = dx+dest->offx, .y = dy+dest->offy, .w = w, .h = h };
683   SDL_BlitSurface(src->srf, &srect, dest->srf, &drect);
684   if (dest == &mainbm) needaflip = TRUE;
685 #endif
686 }
687 
set_font(struct rawbm * bm,int findex,BOOL jam2)688 void set_font(struct rawbm *bm, int findex, BOOL jam2)
689 {
690   if ((bm->fontset) && (bm->findex == findex) && (bm->jam2 == jam2))
691     return;
692 
693 #ifndef __SDL_WRAPPER__
694   struct TextFont *thefont;
695   switch (findex)
696   {
697     case FONT_SFX: thefont = sfxfont; break;
698     case FONT_PRP: thefont = prpfont; break;
699     default:       thefont = fixfont; break;
700   }
701 
702   IGraphics->SetRPAttrs( &bm->rp, RPTAG_DrMd, jam2 ? JAM2 : JAM1, RPTAG_Font, thefont, TAG_DONE );
703   bm->baseline = thefont->tf_Baseline;
704 #else
705   switch (findex)
706   {
707     case FONT_SFX: bm->font = sfxttf; break;
708     case FONT_PRP: bm->font = prpttf; break;
709     default:       bm->font = fixttf; break;
710   }
711 #endif
712 
713   bm->findex  = findex;
714   bm->jam2    = jam2;
715   bm->fontset = TRUE;
716 }
717 
printstr(struct rawbm * bm,const char * str,int x,int y)718 void printstr(struct rawbm *bm, const char *str, int x, int y)
719 {
720 #ifndef __SDL_WRAPPER__
721   IGraphics->Move(&bm->rp, x, y+bm->baseline);
722   IGraphics->Text(&bm->rp, str, strlen(str));
723 #else
724   SDL_Surface *srf;
725   SDL_Rect rect = { .x = x+bm->offx, .y = y+bm->offy };
726   if (bm->jam2)
727   {
728     srf = TTF_RenderText_Shaded(bm->font, str, bm->fsc, bm->bsc);
729   }
730   else
731   {
732     srf = TTF_RenderText_Blended(bm->font, str, bm->fsc);
733   }
734   if (!srf) return;
735   SDL_BlitSurface(srf, NULL, bm->srf, &rect);
736   SDL_FreeSurface(srf);
737 #endif
738 }
739 
printstrlen(struct rawbm * bm,const char * str,int len,int x,int y)740 void printstrlen(struct rawbm *bm, const char *str, int len, int x, int y)
741 {
742 #ifndef __SDL_WRAPPER__
743   IGraphics->Move(&bm->rp, x, y+bm->baseline);
744   IGraphics->Text(&bm->rp, str, len);
745 #else
746   char tmp[len+1];
747   SDL_Surface *srf;
748   SDL_Rect rect = { .x = x+bm->offx, .y = y+bm->offy };
749   strncpy(tmp, str, len);
750   tmp[len] = 0;
751   if (bm->jam2)
752   {
753     srf = TTF_RenderText_Shaded(bm->font, tmp, bm->fsc, bm->bsc);
754   }
755   else
756   {
757     srf = TTF_RenderText_Blended(bm->font, tmp, bm->fsc);
758   }
759   if (!srf) return;
760   SDL_BlitSurface(srf, NULL, bm->srf, &rect);
761   SDL_FreeSurface(srf);
762 #endif
763 }
764 
textfit(struct rawbm * bm,const char * str,int w)765 int textfit( struct rawbm *bm, const char *str, int w )
766 {
767 #ifndef __SDL_WRAPPER__
768   struct TextExtent te;
769   return IGraphics->TextFit( &bm->rp, str, strlen(str), &te, NULL, 1, w, 24 );
770 #else
771   int tw, th, c;
772   char tmp[512];
773   strncpy(tmp, str, 512);
774   tmp[511] = 0;
775 
776   c = strlen(tmp);
777   while (c>0)
778   {
779     TTF_SizeText(bm->font, tmp, &tw, &th);
780     if (tw <= w) break;
781     tmp[--c] = 0;
782   }
783   return c;
784 #endif
785 }
786 
gui_add_zone(struct czone * zn,int32 * numzn,int32 maxz,int16 x,int16 y,int16 w,int16 h)787 int32 gui_add_zone( struct czone *zn, int32 *numzn, int32 maxz, int16 x, int16 y, int16 w, int16 h )
788 {
789   int32 fz;
790 
791   for( fz=0; fz<(*numzn); fz++ )
792     if( zn[fz].x == -1 ) break;
793 
794   if( fz == *numzn )
795   {
796     if( (*numzn) == maxz )
797       return -1;
798     (*numzn)++;
799   }
800 
801   zn[fz].x = x;
802   zn[fz].y = y;
803   zn[fz].w = w;
804   zn[fz].h = h;
805 
806 //  printf( "z: %ld = %d,%d,%d,%d\n", fz, x, y, w, h );
807 
808   return fz;
809 }
810 
gui_set_nbox(struct numberbox * nb,int16 x,int16 y,int16 w,int16 h,int32 min,int32 max,int32 cnum,const TEXT * fmt,uint16 flags)811 void gui_set_nbox( struct numberbox *nb, int16 x, int16 y, int16 w, int16 h, int32 min, int32 max, int32 cnum, const TEXT *fmt, uint16 flags )
812 {
813   nb->x = x;
814   nb->y = y;
815   nb->w = w;
816   nb->h = h;
817   nb->min = min;
818   nb->max = max;
819   nb->cnum = cnum;
820   nb->flags = flags;
821   nb->pressed = 0;
822 
823   if( fmt == NULL )
824     strcpy( nb->fmt, "%d" );
825   else
826     strcpy( nb->fmt, fmt );
827 }
828 
gui_zap_zone(struct czone * zn,int32 * numzn,int32 max,int32 * zone)829 void gui_zap_zone( struct czone *zn, int32 *numzn, int32 max, int32 *zone )
830 {
831   int32 tz;
832 
833   tz = *zone;
834   *zone = -1;
835 
836   if( ( tz < 0 ) || ( tz >= max ) )
837     return;
838 
839   zn[tz].x = -1;
840 
841   if( (*numzn) == 0 ) return;
842 
843   while( (*numzn) > 0 )
844   {
845     if( zn[(*numzn)-1].x != -1 ) break;
846     (*numzn)--;
847   }
848 }
849 
gui_get_zone(struct czone * zn,int32 numz,int16 x,int16 y)850 int32 gui_get_zone( struct czone *zn, int32 numz, int16 x, int16 y )
851 {
852   int32 i;
853 
854   for( i=0; i<numz; i++ )
855   {
856     if( zn[i].x != -1 )
857     {
858       if( ( x >= zn[i].x ) &&
859           ( y >= zn[i].y ) &&
860           ( x < ( zn[i].x+zn[i].w ) ) &&
861           ( y < ( zn[i].y+zn[i].h ) ) )
862         return i;
863     }
864   }
865 
866   return -1;
867 }
868 
make_image(struct rawbm * bm,uint16 w,uint16 h)869 BOOL make_image( struct rawbm *bm, uint16 w, uint16 h )
870 {
871   bm->w = w;
872   bm->h = h;
873   bm->fontset = FALSE;
874   bm->fpenset = FALSE;
875   bm->bpenset = FALSE;
876 #ifndef __SDL_WRAPPER__
877   IGraphics->InitRastPort( &bm->rp );
878   bm->bm = IGraphics->AllocBitMap( bm->w, bm->h, 8, 0, mainwin->RPort->BitMap );
879   if( !bm->bm )
880   {
881     printf( "Out of memory @ %s:%d\n", __FILE__, __LINE__ );
882     return FALSE;
883   }
884   bm->rp.BitMap = bm->bm;
885 #else
886   bm->offx = 0;
887   bm->offy = 0;
888   bm->srf = SDL_CreateRGBSurface(SRFTYPE, w, h, srfdepth, 0, 0, 0, 0);
889   if( !bm->srf )
890   {
891     printf( "Out of memory @ %s:%d\n", __FILE__, __LINE__ );
892     return FALSE;
893   }
894 #endif
895   return TRUE;
896 }
897 
open_image(const TEXT * name,struct rawbm * bm)898 BOOL open_image( const TEXT *name, struct rawbm *bm )
899 {
900 #ifndef __SDL_WRAPPER__
901   uint8 *data;
902   Object *io = NULL;
903   struct BitMapHeader *bmh;
904   struct RenderInfo ri;
905   TEXT tmp[1024];
906 
907   strcpy( tmp, skindir );
908   IDOS->AddPart( tmp, name, 1024 );
909   strcat( tmp, skinext );
910 
911   io = IDataTypes->NewDTObject( tmp,
912     DTA_SourceType,        DTST_FILE,
913     DTA_GroupID,           GID_PICTURE,
914     PDTA_FreeSourceBitMap, TRUE,
915     PDTA_DestMode,         PMODE_V43,
916     TAG_DONE );
917 
918   if( !io )
919   {
920     printf( "Error opening '%s'\n", tmp );
921     return FALSE;
922   }
923 
924   if( IDataTypes->GetDTAttrs( io,
925     PDTA_BitMapHeader,     &bmh,
926     TAG_DONE ) == 0 )
927   {
928     IDataTypes->DisposeDTObject( io );
929     printf( "Unable to get information about '%s'\n", tmp );
930     return FALSE;
931   }
932 
933   bm->w      = bmh->bmh_Width;
934   bm->h      = bmh->bmh_Height;
935 
936   IGraphics->InitRastPort( &bm->rp );
937   bm->bm = IGraphics->AllocBitMap( bm->w, bm->h, 8, 0, mainwin->RPort->BitMap );
938   if( !bm->bm )
939   {
940     IDataTypes->DisposeDTObject( io );
941     printf( "Out of memory @ %s:%d\n", __FILE__, __LINE__ );
942     return FALSE;
943   }
944 
945   bm->rp.BitMap = bm->bm;
946 
947   data   = IExec->AllocVecTags( bm->w*bm->h*4, TAG_DONE );
948   if( !data )
949   {
950     IDataTypes->DisposeDTObject( io );
951     IGraphics->FreeBitMap( bm->bm );
952     printf( "Out of memory @ %s:%d\n", __FILE__, __LINE__ );
953     return FALSE;
954   }
955 
956   IIntuition->IDoMethod( io, PDTM_READPIXELARRAY, data, PBPAFMT_ARGB, bm->w<<2, 0, 0, bm->w,bm->h );
957 
958   ri.Memory      = data;
959   ri.BytesPerRow = bm->w<<2;
960   ri.RGBFormat   = RGBFB_A8R8G8B8;
961   IP96->p96WritePixelArray( &ri, 0, 0, &bm->rp, 0, 0, bm->w, bm->h );
962 
963   IExec->FreeVec( data );
964   IDataTypes->DisposeDTObject( io );
965 #else
966   SDL_Surface *tmpsrf;
967   TEXT tmp[1024];
968 
969 #ifdef __APPLE__
970   if (strncmp(skindir, "Skins/", 6) == 0)
971     osxGetResourcesPath(tmp, skindir);
972 #else
973   strncpy( tmp, skindir, 1024 );
974 #endif
975   strncat( tmp, "/", 1024 );
976   strncat( tmp, name, 1024 );
977   strncat( tmp, skinext, 1024 );
978 
979   tmpsrf = IMG_Load(tmp);
980   if (!tmpsrf)
981   {
982     printf("Error loading '%s': %s\n", tmp, IMG_GetError());
983     return FALSE;
984   }
985 
986   if (!make_image(bm, tmpsrf->w, tmpsrf->h))
987   {
988     SDL_FreeSurface(tmpsrf);
989     return FALSE;
990   }
991   /* Convert to the screen surface format */
992   SDL_BlitSurface(tmpsrf, NULL, bm->srf, NULL);
993   SDL_FreeSurface(tmpsrf);
994 #endif
995   return TRUE;
996 }
997 
gui_set_tbox(struct textbox * tb,int16 x,int16 y,int16 w,TEXT * content,int32 maxlen,int16 flags,int16 inpanel)998 BOOL gui_set_tbox( struct textbox *tb, int16 x, int16 y, int16 w, TEXT *content, int32 maxlen, int16 flags, int16 inpanel )
999 {
1000   tb->x = x;
1001   tb->y = y;
1002   tb->w = w;
1003   tb->content = content;
1004   tb->maxlen = maxlen;
1005   tb->flags = flags;
1006   tb->spos = 0;
1007   tb->cpos = 0;
1008   tb->inpanel = inpanel;
1009 
1010   if( !make_image( &tb->bm, w, 16 ) ) return FALSE;
1011 
1012   set_font(&tb->bm, FONT_FIX, FALSE);
1013   return TRUE;
1014 }
1015 
put_partbitmap(uint32 bm,uint16 bx,uint16 by,uint16 x,uint16 y,uint16 w,uint16 h)1016 void put_partbitmap( uint32 bm, uint16 bx, uint16 by, uint16 x, uint16 y, uint16 w, uint16 h )
1017 {
1018 #ifndef __SDL_WRAPPER__
1019   IGraphics->BltBitMapRastPort( bitmaps[bm].bm, bx, by, mainwin->RPort, x, y, w, h, 0x0C0 );
1020 #else
1021   SDL_Rect srect = { .x = bx+bitmaps[bm].offx, .y = by+bitmaps[bm].offy, .w = w, .h = h };
1022   SDL_Rect drect = { .x = x , .y =  y, .w = w, .h = h };
1023   SDL_BlitSurface(bitmaps[bm].srf, &srect, ssrf, &drect);
1024   needaflip = TRUE;
1025 #endif
1026 }
1027 
put_bitmap(uint32 bm,uint16 x,uint16 y,uint16 w,uint16 h)1028 void put_bitmap( uint32 bm, uint16 x, uint16 y, uint16 w, uint16 h )
1029 {
1030 #ifndef __SDL_WRAPPER__
1031   IGraphics->BltBitMapRastPort( bitmaps[bm].bm, 0, 0, mainwin->RPort, x, y, w, h, 0x0C0 );
1032 #else
1033   SDL_Rect srect = { .x = bitmaps[bm].offx, .y = bitmaps[bm].offy, .w = w, .h = h };
1034   SDL_Rect drect = { .x = x, .y = y, .w = w, .h = h };
1035   SDL_BlitSurface(bitmaps[bm].srf, &srect, ssrf, &drect);
1036   needaflip = TRUE;
1037 #endif
1038 }
1039 
put_ppartbitmap(uint32 bm,uint16 bx,uint16 by,uint16 x,uint16 y,uint16 w,uint16 h)1040 void put_ppartbitmap( uint32 bm, uint16 bx, uint16 by, uint16 x, uint16 y, uint16 w, uint16 h )
1041 {
1042 #ifndef __SDL_WRAPPER__
1043   IGraphics->BltBitMapRastPort( bitmaps[bm].bm, bx, by, prefwin->RPort, x+pw_bl, y+pw_bt, w, h, 0x0C0 );
1044 #else
1045   SDL_Rect srect = { .x = bx+bitmaps[bm].offx, .y = by+bitmaps[bm].offy, .w = w, .h = h };
1046   SDL_Rect drect = { .x = x+4 , .y =  y+4, .w = w, .h = h };
1047   SDL_BlitSurface(bitmaps[bm].srf, &srect, prefbm.srf, &drect);
1048 #endif
1049 }
1050 
put_pbitmap(uint32 bm,uint16 x,uint16 y,uint16 w,uint16 h)1051 void put_pbitmap( uint32 bm, uint16 x, uint16 y, uint16 w, uint16 h )
1052 {
1053 #ifndef __SDL_WRAPPER__
1054   IGraphics->BltBitMapRastPort( bitmaps[bm].bm, 0, 0, prefwin->RPort, x+pw_bl, y+pw_bt, w, h, 0x0C0 );
1055 #else
1056   SDL_Rect srect = { .x = bitmaps[bm].offx, .y = bitmaps[bm].offy, .w = w, .h = h };
1057   SDL_Rect drect = { .x = x+4, .y = y+4, .w = w, .h = h };
1058   SDL_BlitSurface(bitmaps[bm].srf, &srect, prefbm.srf, &drect);
1059   needaflip = TRUE;
1060 #endif
1061 }
1062 
gui_render_nbox(struct ahx_tune * at,int32 panel,struct numberbox * nb)1063 void gui_render_nbox( struct ahx_tune *at, int32 panel, struct numberbox *nb )
1064 {
1065   TEXT pbuf[32];
1066 
1067   if( nb->cnum < nb->min ) nb->cnum = nb->min;
1068   if( nb->cnum > nb->max ) nb->cnum = nb->max;
1069 
1070   if( panel != at->at_curpanel )
1071     return;
1072 
1073   set_fpen(&mainbm, PAL_BACK);
1074   fillrect_xy(&mainbm, nb->x, nb->y, nb->x+nb->w-25, nb->y+nb->h-1);
1075 
1076   set_font(&mainbm, FONT_FIX, FALSE);
1077 
1078   if( ( nb->flags & NBF_ENABLED ) != 0 )
1079     set_fpen(&mainbm, PAL_TEXT);
1080   else
1081     set_fpen(&mainbm, PAL_DISABLEDTEXT);
1082 
1083   switch( nb->flags & (NBF_WAVELEN|NBF_ONOFF) )
1084   {
1085     case NBF_WAVELEN:
1086       sprintf( pbuf, nb->fmt, (4L<<nb->cnum) );
1087       break;
1088 
1089     case NBF_ONOFF:
1090       if( nb->cnum )
1091         strcpy( pbuf, "On " );
1092       else
1093         strcpy( pbuf, "Off" );
1094       break;
1095 
1096     default:
1097       sprintf( pbuf, nb->fmt, nb->cnum );
1098   }
1099   printstr(&mainbm, pbuf, nb->x+4, nb->y);
1100 
1101   put_partbitmap( BM_PLUSMINUS, 0, 0, nb->x+nb->w-28, nb->y-1, 28, 19 );
1102   nb->pressed = 0;
1103 }
1104 
gui_render_tbox(struct rawbm * bm,struct textbox * tb)1105 void gui_render_tbox( struct rawbm *bm, struct textbox *tb )
1106 {
1107   int16 panel;
1108   int32 w;
1109 
1110   if( ( tb->flags & TBF_VISIBLE ) == 0 ) return;
1111 
1112   if( bm == &mainbm )
1113   {
1114     panel = PN_TRACKER;
1115     if( curtune )
1116       panel = curtune->at_curpanel;
1117 
1118     if( panel != tb->inpanel ) return;
1119   }
1120 
1121   set_fpen(&tb->bm, PAL_BACK);
1122   fillrect_xy(&tb->bm, 0, 0, tb->w-1, 15);
1123 
1124   if( tb->content == NULL )
1125   {
1126     bm_to_bm(&tb->bm, 0, 0, bm, tb->x, tb->y, tb->w, 16);
1127     return;
1128   }
1129 
1130   if( tb->cpos < 0 ) tb->cpos = 0;
1131 
1132   if( tb->cpos > strlen( tb->content ) )
1133     tb->cpos = strlen( tb->content );
1134 
1135   if( tb->cpos < tb->spos ) tb->spos = tb->cpos;
1136   if( tb->cpos >= (tb->spos + (tb->w>>3)) )
1137     tb->spos = tb->cpos - ((tb->w>>3)-1);
1138 
1139   w = strlen( &tb->content[tb->spos] );
1140   if( w > (tb->w>>3) ) w = (tb->w>>3);
1141 
1142   if( tb->flags & TBF_ACTIVE )
1143   {
1144     set_fpen(&tb->bm, PAL_BARLIGHT);
1145     fillrect_xy(&tb->bm, (tb->cpos-tb->spos)*8, 0, (tb->cpos-tb->spos)*8+7, 15);
1146   }
1147 
1148   if( tb->flags & TBF_ENABLED )
1149     set_fpen(&tb->bm, PAL_TEXT);
1150   else
1151     set_fpen(&tb->bm, PAL_DISABLEDTEXT);
1152 
1153   printstrlen(&tb->bm, &tb->content[tb->spos], w, 0, 0);
1154 
1155   bm_to_bm(&tb->bm, 0, 0, bm, tb->x, tb->y, tb->w, 16);
1156 }
1157 
gui_render_perf(struct ahx_tune * at,struct ahx_instrument * ins,BOOL force)1158 void gui_render_perf( struct ahx_tune *at, struct ahx_instrument *ins, BOOL force )
1159 {
1160   TEXT pbuf[32];
1161   int32 i, j, k, n;
1162   int32 cx, cy, mx, my;
1163 
1164   if( ins == NULL )
1165   {
1166     set_fpen(&mainbm, PAL_BACK);
1167     fillrect_xy(&mainbm, PERF_X, PERF_Y, PERF_MX, PERF_MY);
1168     perf_lastinst = NULL;
1169     return;
1170   }
1171 
1172   if( ins->ins_pcury < 0 ) ins->ins_pcury = 0;
1173   if( ins->ins_pcury > 254 ) ins->ins_pcury = 254;
1174 
1175   if( ins->ins_pcurx < 0 ) ins->ins_pcurx = 0;
1176   if( ins->ins_pcurx > 7 ) ins->ins_pcurx = 7;
1177 
1178   if( ins->ins_pcury < ins->ins_ptop ) ins->ins_ptop = ins->ins_pcury;
1179   if( ins->ins_pcury >= ins->ins_ptop+(PERF_H>>4) )
1180     ins->ins_ptop = ins->ins_pcury-((PERF_H>>4)-1);
1181 
1182   if( ins->ins_ptop < 0 ) ins->ins_ptop = 0;
1183   if( ins->ins_ptop > 255-(PERF_H>>4) ) ins->ins_ptop = (255-(PERF_H>>4));
1184 
1185   if( ( force == FALSE ) &&
1186       ( ins == perf_lastinst ) &&
1187       ( ins->ins_ptop == perf_laststep ) &&
1188       ( ins->ins_pcurx == perf_lastcx ) &&
1189       ( ins->ins_pcury == perf_lastcy ) &&
1190       ( ins->ins_PList.pls_Length == perf_lastplen ) )
1191     return;
1192 
1193   perf_lastinst = ins;
1194   perf_laststep = ins->ins_ptop;
1195   perf_lastcx   = ins->ins_pcurx;
1196   perf_lastcy   = ins->ins_pcury;
1197   perf_lastplen = ins->ins_PList.pls_Length;
1198 
1199   set_fpen(&bitmaps[BM_PERF], PAL_BACK);
1200   fillrect_xy(&bitmaps[BM_PERF], 0, 0, PERF_MX, PERF_MY);
1201 
1202   set_pens(&bitmaps[BM_PERF], PAL_TEXT, PAL_BACK);
1203 
1204   if( ins->ins_ptop >= ins->ins_PList.pls_Length )
1205     set_fpen(&bitmaps[BM_PERF], PAL_DISABLEDTEXT);
1206 
1207   k = ins->ins_pcury - ins->ins_ptop;
1208 
1209   for( i=0, j=ins->ins_ptop; i<(PERF_H>>4); i++, j++ )
1210   {
1211     if( j > 254 ) break;
1212 
1213     if( j == ins->ins_pcury )
1214       set_bpen(&bitmaps[BM_PERF], PAL_BARMID);
1215     if( j == ins->ins_pcury+1 )
1216       set_bpen(&bitmaps[BM_PERF], PAL_BACK);
1217 
1218     if( j == ins->ins_PList.pls_Length )
1219       set_fpen(&bitmaps[BM_PERF], PAL_DISABLEDTEXT);
1220 
1221     n = ins->ins_PList.pls_Entries[j].ple_Note;
1222     if( n > 60 ) n = 0;
1223 
1224     sprintf( pbuf, "%03d %s%c %01d %01X%02X %01X%02X ",
1225       (int)j,
1226       notenames[n],
1227       ins->ins_PList.pls_Entries[j].ple_Fixed ? '*' : ' ',
1228       ins->ins_PList.pls_Entries[j].ple_Waveform,
1229       ins->ins_PList.pls_Entries[j].ple_FX[0]&0xf,
1230       ins->ins_PList.pls_Entries[j].ple_FXParam[0]&0xff,
1231       ins->ins_PList.pls_Entries[j].ple_FX[1]&0xf,
1232       ins->ins_PList.pls_Entries[j].ple_FXParam[1]&0xff );
1233 
1234     printstr(&bitmaps[BM_PERF], pbuf, 0, (i*16)+4);
1235   }
1236 
1237   if( k >= 0 )
1238   {
1239     set_fpen(&bitmaps[BM_PERF], PAL_BARLIGHT);
1240     fillrect_xy(&bitmaps[BM_PERF], 0, k*16+3, PERF_MX, k*16+3);
1241   }
1242 
1243   if( k < ((PERF_H>>4)-1) )
1244   {
1245     set_fpen(&bitmaps[BM_PERF], PAL_BARDARK);
1246     fillrect_xy(&bitmaps[BM_PERF], 0, k*16+20, PERF_MX, k*16+20);
1247   }
1248 
1249   set_fpen(&bitmaps[BM_PERF], PAL_CURSNORM);
1250   fillrect_xy(&bitmaps[BM_PERF],  3*8+4, 0,  3*8+4, PERF_MY);
1251   fillrect_xy(&bitmaps[BM_PERF],  8*8+4, 0,  8*8+4, PERF_MY);
1252   fillrect_xy(&bitmaps[BM_PERF], 10*8+4, 0, 10*8+4, PERF_MY);
1253   fillrect_xy(&bitmaps[BM_PERF], 14*8+4, 0, 14*8+4, PERF_MY);
1254 
1255   if( at->at_idoing == D_EDITING )
1256     set_fpen(&bitmaps[BM_PERF], PAL_CURSEDIT);
1257   else
1258     set_fpen(&bitmaps[BM_PERF], PAL_CURSNORM);
1259 
1260   cx = perf_xoff[ins->ins_pcurx]-2;
1261   cy = (k<<4)+2;
1262   mx = cx+8+3;
1263   my = cy+16+3;
1264 
1265   if( ins->ins_pcurx == 0 )
1266     mx = cx+32+3;
1267 
1268   fillrect_xy(&bitmaps[BM_PERF], cx, cy, mx, cy+1);
1269   fillrect_xy(&bitmaps[BM_PERF], cx, my-1, mx, my);
1270   fillrect_xy(&bitmaps[BM_PERF], cx, cy, cx+1, my);
1271   fillrect_xy(&bitmaps[BM_PERF], mx-1, cy, mx, my);
1272 
1273   put_bitmap( BM_PERF, PERF_X, PERF_Y, PERF_W, PERF_H );
1274 }
1275 
gui_render_inslistb(BOOL force)1276 void gui_render_inslistb( BOOL force )
1277 {
1278   struct ahx_tune *at;
1279   struct ahx_instrument *in;
1280   int16 curi;
1281   int32 i, j, k;
1282   TEXT tmp[32];
1283 
1284   curi = 0;
1285 
1286   at = curtune;
1287   if( at )
1288   {
1289     if( at->at_curpanel != PN_INSED )
1290       return;
1291 
1292     curi = at->at_curins;
1293   }
1294 
1295   if( ( inslsb_lastcuri == curi ) &&
1296       ( inslsb_lasttune == at ) &&
1297       ( inslsb_lasttopi == at->at_topinsb ) &&
1298       ( force == FALSE ) )
1299     return;
1300 
1301   set_fpen(&bitmaps[BM_INSLISTB], PAL_BACK);
1302   fillrect_xy(&bitmaps[BM_INSLISTB], 0, 0, INSLSTB_MX, INSLSTB_MY);
1303 
1304   if( at )
1305   {
1306     if( curi < at->at_topinsb )     at->at_topinsb = curi;
1307     if( curi > (at->at_topinsb+((INSLSTB_H>>4)-1)) ) at->at_topinsb = curi-((INSLSTB_H>>4)-1);
1308 
1309     if( at->at_topinsb < 1 ) at->at_topinsb = 1;
1310 
1311     set_pens(&bitmaps[BM_INSLISTB], PAL_TEXT, PAL_BACK);
1312     for( i=0, j=at->at_topinsb; i<(INSLSTB_H>>4); i++, j++ )
1313     {
1314       sprintf( tmp, "%02d                   ", (int)j );
1315       in = &at->at_Instruments[j];
1316 
1317       for( k=0; k<18; k++ )
1318       {
1319         if( in->ins_Name[k] == 0 ) break;
1320         tmp[k+3] = in->ins_Name[k];
1321       }
1322 
1323       if( j == curi )
1324         set_bpen(&bitmaps[BM_INSLISTB], PAL_BARMID);
1325       if( j == curi+1 )
1326         set_bpen(&bitmaps[BM_INSLISTB], PAL_BACK);
1327 
1328       printstrlen(&bitmaps[BM_INSLISTB], tmp, 24, 0, i*16+4);
1329     }
1330 
1331     if( curi >= at->at_topinsb )
1332     {
1333       k = (curi-at->at_topinsb)*16+4;
1334       set_fpen(&bitmaps[BM_INSLISTB], PAL_BARLIGHT);
1335       fillrect_xy(&bitmaps[BM_INSLISTB], 0, k-1, INSLSTB_MX, k-1);
1336       set_fpen(&bitmaps[BM_INSLISTB], PAL_BARDARK);
1337       fillrect_xy(&bitmaps[BM_INSLISTB], 0, k+16, INSLSTB_MX, k+16);
1338     }
1339 
1340     set_fpen(&bitmaps[BM_INSLISTB], PAL_TEXT);
1341     fillrect_xy(&bitmaps[BM_INSLISTB], 20, 0, 20, INSLSTB_MY);
1342   }
1343 
1344   put_bitmap( BM_INSLISTB, INSLSTB_X, INSLSTB_Y, INSLSTB_W, INSLSTB_H );
1345 
1346   inslsb_lastcuri = curi;
1347   inslsb_lasttune = at;
1348   inslsb_lasttopi = at->at_topinsb;
1349 }
1350 
gui_check_nb(struct ahx_tune * at,uint32 nb,int32 val)1351 void gui_check_nb( struct ahx_tune *at, uint32 nb, int32 val )
1352 {
1353   if( trk_nb[nb].cnum != val )
1354   {
1355     trk_nb[nb].cnum = val;
1356     gui_render_nbox( at, PN_TRACKER, &trk_nb[nb] );
1357   }
1358 }
1359 
gui_check_inb(struct ahx_tune * at,uint32 nb,int32 val)1360 void gui_check_inb( struct ahx_tune *at, uint32 nb, int32 val )
1361 {
1362   if( ins_nb[nb].cnum != val )
1363   {
1364     ins_nb[nb].cnum = val;
1365     gui_render_nbox( at, PN_INSED, &ins_nb[nb] );
1366   }
1367 }
1368 
gui_set_various_things(struct ahx_tune * at)1369 void gui_set_various_things( struct ahx_tune *at )
1370 {
1371   int32 i;
1372 
1373   if( at->at_NextPosNr != -1 )
1374     gui_check_nb( at, NB_POSNR, at->at_NextPosNr );
1375   else
1376     gui_check_nb( at, NB_POSNR, at->at_PosNr );
1377 
1378   gui_check_nb( at, NB_LENGTH, at->at_PositionNr );
1379   gui_check_nb( at, NB_TRKLEN, at->at_TrackLength );
1380   gui_check_nb( at, NB_RESPOS, at->at_Restart );
1381   gui_check_nb( at, NB_SSNR,   at->at_SubsongNr );
1382 
1383   if( at->at_SubsongNr > 0 )
1384   {
1385     if( ( trk_nb[NB_CURSS].cnum != at->at_curss ) || ( ( trk_nb[NB_CURSS].flags & NBF_ENABLED ) == 0 ) )
1386     {
1387       trk_nb[NB_CURSS].flags |= NBF_ENABLED;
1388       trk_nb[NB_CURSS].cnum = at->at_curss;
1389       gui_render_nbox( at, PN_TRACKER, &trk_nb[NB_CURSS] );
1390     }
1391   } else {
1392     if( ( trk_nb[NB_CURSS].flags & NBF_ENABLED ) != 0 )
1393     {
1394       trk_nb[NB_CURSS].flags &= ~NBF_ENABLED;
1395       trk_nb[NB_CURSS].cnum = 0;
1396       gui_render_nbox( at, PN_TRACKER, &trk_nb[NB_CURSS] );
1397     }
1398   }
1399 
1400   if( at->at_curss > 0 )
1401   {
1402     if( ( trk_nb[NB_SSPOS].cnum != at->at_Subsongs[at->at_curss-1] ) ||
1403         ( ( trk_nb[NB_SSPOS].flags & NBF_ENABLED ) == 0 ) )
1404     {
1405       if( at->at_SubsongNr > 0 )
1406       {
1407         trk_nb[NB_SSPOS].flags |= NBF_ENABLED;
1408         trk_nb[NB_SSPOS].cnum = at->at_Subsongs[at->at_curss-1];
1409         gui_render_nbox( at, PN_TRACKER, &trk_nb[NB_SSPOS] );
1410       } else {
1411         trk_nb[NB_SSPOS].flags &= ~NBF_ENABLED;
1412         trk_nb[NB_SSPOS].cnum = 0;
1413         gui_render_nbox( at, PN_TRACKER, &trk_nb[NB_SSPOS] );
1414       }
1415     }
1416   } else {
1417     if( ( trk_nb[NB_SSPOS].flags & NBF_ENABLED ) != 0 )
1418     {
1419       trk_nb[NB_SSPOS].cnum = 0;
1420       trk_nb[NB_SSPOS].flags &= ~NBF_ENABLED;
1421       gui_render_nbox( at, PN_TRACKER, &trk_nb[NB_SSPOS] );
1422     }
1423   }
1424 
1425   gui_check_nb( at, NB_CHANS,       at->at_Channels );
1426   gui_check_nb( at, NB_MIXG,        at->at_mixgainP );
1427   gui_check_nb( at, NB_SPEEDMULT,   at->at_SpeedMultiplier );
1428   gui_check_nb( at, NB_DRUMPADMODE, at->at_drumpadmode );
1429 
1430   if( ( at != NULL ) && ( ins_nb[INB_INS].cnum != at->at_curins ) )
1431   {
1432     ins_nb[INB_INS].cnum = at->at_curins;
1433     gui_render_nbox( at, PN_INSED, &ins_nb[INB_INS] );
1434   }
1435 
1436   if( ( at == NULL ) || ( at->at_curins == 0 ) )
1437   {
1438     for( i=1; i<INB_END; i++ )
1439     {
1440       ins_nb[i].cnum = ins_nb[i].min;
1441       ins_nb[i].flags &= ~NBF_ENABLED;
1442       gui_render_nbox( at, PN_INSED, &ins_nb[i] );
1443     }
1444   } else {
1445     struct ahx_instrument *ip;
1446 
1447     ip = &at->at_Instruments[at->at_curins];
1448 
1449     for( i=1; i<INB_END; i++ )
1450     {
1451       ins_nb[i].flags |= NBF_ENABLED;
1452       gui_render_nbox( at, PN_INSED, &ins_nb[i] );
1453     }
1454 
1455     gui_check_inb( at, INB_VOL,     ip->ins_Volume );
1456     gui_check_inb( at, INB_WAVELEN, ip->ins_WaveLength );
1457 
1458     switch( ip->ins_WaveLength )
1459     {
1460       case 0:
1461         i = 0x20;
1462         break;
1463       case 1:
1464         i = 0x10;
1465         break;
1466       case 2:
1467         i = 0x08;
1468         break;
1469       case 3:
1470         i = 0x04;
1471         break;
1472       case 4:
1473         i = 0x02;
1474         break;
1475       default:
1476         i = 0x01;
1477         break;
1478     }
1479 
1480     ins_nb[INB_SQRLOWER].min = i;
1481     ins_nb[INB_SQRUPPER].min = i;
1482 
1483     if( ip->ins_SquareLowerLimit < i )
1484       ip->ins_SquareLowerLimit = i;
1485     if( ip->ins_SquareUpperLimit < i )
1486       ip->ins_SquareUpperLimit = i;
1487 
1488     gui_check_inb( at, INB_ATTACK,    ip->ins_Envelope.aFrames );
1489     gui_check_inb( at, INB_AVOL,      ip->ins_Envelope.aVolume );
1490     gui_check_inb( at, INB_DECAY,     ip->ins_Envelope.dFrames );
1491     gui_check_inb( at, INB_DVOL,      ip->ins_Envelope.dVolume );
1492     gui_check_inb( at, INB_SUSTAIN,   ip->ins_Envelope.sFrames );
1493     gui_check_inb( at, INB_RELEASE,   ip->ins_Envelope.rFrames );
1494     gui_check_inb( at, INB_RVOL,      ip->ins_Envelope.rVolume );
1495     gui_check_inb( at, INB_VIBDELAY,  ip->ins_VibratoDelay );
1496     gui_check_inb( at, INB_VIBDEPTH,  ip->ins_VibratoDepth );
1497     gui_check_inb( at, INB_VIBSPEED,  ip->ins_VibratoSpeed );
1498     gui_check_inb( at, INB_SQRLOWER,  ip->ins_SquareLowerLimit );
1499     gui_check_inb( at, INB_SQRUPPER,  ip->ins_SquareUpperLimit );
1500     gui_check_inb( at, INB_SQRSPEED,  ip->ins_SquareSpeed );
1501     gui_check_inb( at, INB_FLTLOWER,  ip->ins_FilterLowerLimit );
1502     gui_check_inb( at, INB_FLTUPPER,  ip->ins_FilterUpperLimit );
1503     gui_check_inb( at, INB_FLTSPEED,  ip->ins_FilterSpeed );
1504     gui_check_inb( at, INB_PERFSPEED, ip->ins_PList.pls_Speed );
1505     gui_check_inb( at, INB_PERFLEN,   ip->ins_PList.pls_Length );
1506     gui_check_inb( at, INB_HARDCUT,   ip->ins_HardCutReleaseFrames );
1507     gui_check_inb( at, INB_RELCUT,    ip->ins_HardCutRelease );
1508   }
1509 
1510   if( at == NULL )
1511   {
1512     if( tbx[TB_SONGNAME].content != NULL )
1513     {
1514       tbx[TB_SONGNAME].content = NULL;
1515       gui_render_tbox( &mainbm, &tbx[TB_SONGNAME] );
1516     }
1517   } else {
1518     if( tbx[TB_SONGNAME].content != at->at_Name )
1519     {
1520       tbx[TB_SONGNAME].content = at->at_Name;
1521       tbx[TB_SONGNAME].spos = 0;
1522       tbx[TB_SONGNAME].cpos = 0;
1523       gui_render_tbox( &mainbm, &tbx[TB_SONGNAME] );
1524     }
1525   }
1526 
1527   if( at == NULL )
1528   {
1529     if( tbx[TB_INSNAME].content != NULL )
1530     {
1531       tbx[TB_INSNAME].content = NULL;
1532       gui_render_tbox( &mainbm, &tbx[TB_INSNAME] );
1533     }
1534   } else {
1535     if( tbx[TB_INSNAME].content != at->at_Instruments[at->at_curins].ins_Name )
1536     {
1537       tbx[TB_INSNAME].content = at->at_Instruments[at->at_curins].ins_Name;
1538       tbx[TB_INSNAME].spos = 0;
1539       tbx[TB_INSNAME].cpos = 0;
1540       gui_render_tbox( &mainbm, &tbx[TB_INSNAME] );
1541     }
1542   }
1543 
1544   if( ( curtune ) && ( curtune->at_curpanel == PN_INSED ) )
1545   {
1546     gui_render_perf( curtune, &curtune->at_Instruments[curtune->at_curins], FALSE );
1547     gui_render_inslistb( FALSE );
1548   }
1549 }
1550 
gui_setup_trkbbank(int32 which)1551 void gui_setup_trkbbank( int32 which )
1552 {
1553   int32 i;
1554 
1555   // Blank the bank!
1556   for( i=0; i<12; i++ )
1557   {
1558     tbank[i].x       = 744;
1559     tbank[i].y       = 120+200 + i*23;
1560     tbank[i].name    = NULL;
1561     tbank[i].action  = BBA_NOTHING;
1562     tbank[i].raction = BBA_NOTHING;
1563   }
1564 
1565   switch( which )
1566   {
1567     case 0:
1568       tbank[0].name   = "Cut";
1569       tbank[0].action = BBA_CUTTRK;
1570       tbank[0].raction= BBA_CUTTRK;
1571       tbank[1].name   = "Copy";
1572       tbank[1].action = BBA_COPYTRK;
1573       tbank[1].raction= BBA_COPYTRK;
1574       tbank[2].name   = "Paste";
1575       tbank[2].action = BBA_PASTE;
1576       tbank[2].raction= BBA_PASTE;
1577       tbank[3].name   = "Nt. Up";
1578       tbank[3].action = BBA_NOTEUP;
1579       tbank[4].name   = "Nt. Dn";
1580       tbank[4].action = BBA_NOTEDN;
1581       tbank[5].name   = "Scl. Up";
1582       tbank[5].action = BBA_SCRLUP;
1583       tbank[6].name   = "Scl. Dn";
1584       tbank[6].action = BBA_SCRLDN;
1585       tbank[7].name   = "Rvrs.";
1586       tbank[7].action = BBA_REVERSE;
1587       break;
1588   }
1589 
1590   set_font(&mainbm, FONT_PRP, FALSE);
1591 
1592   for( i=0; i<11; i++ )
1593   {
1594     if( tbank[i].name != NULL )
1595     {
1596 #ifndef __SDL_WRAPPER__
1597       tbank[i].xo = 26 - ( IGraphics->TextLength( &mainbm.rp, tbank[i].name, strlen( tbank[i].name ) ) >> 1 );
1598 #else
1599       int w, h;
1600       TTF_SizeText(mainbm.font, tbank[i].name, &w, &h);
1601       tbank[i].xo = 26 - (w/2);
1602 #endif
1603     }
1604   }
1605 }
1606 
gui_setup_buttonbank(int32 which)1607 void gui_setup_buttonbank( int32 which )
1608 {
1609   int32 i;
1610 
1611   // Blank the bank!
1612   for( i=0; i<16; i++ )
1613   {
1614     bbank[i].x       = 256 + (i&3)*80;
1615     bbank[i].y       = (i>>2)*24;
1616     bbank[i].name    = NULL;
1617     bbank[i].action  = BBA_NOTHING;
1618     bbank[i].raction = BBA_NOTHING;
1619   }
1620 
1621   switch( which )
1622   {
1623     case 0:
1624       bbank[0].name    = "New Tab";
1625       bbank[0].action  = BBA_NEWTAB;
1626       bbank[0].raction = BBA_CLONETAB;
1627       bbank[1].name    = "Load Mod";
1628       bbank[1].action  = BBA_LOADTUNE;
1629       bbank[2].name    = "Save AHX";
1630       bbank[2].action  = BBA_SAVEAHX;
1631       bbank[3].name    = "Save HVL";
1632       bbank[3].action  = BBA_SAVEHVL;
1633       bbank[4].name    = "Load Ins";
1634       bbank[4].action  = BBA_LOADINS;
1635       bbank[5].name    = "Save Ins";
1636       bbank[5].action  = BBA_SAVEINS;
1637       bbank[6].name    = "Ins Edit";
1638       bbank[6].action  = BBA_INSEDIT;
1639       bbank[7].name    = "Prefs";
1640       bbank[7].action  = BBA_PREFS;
1641       bbank[8].name    = "Autogain";
1642       bbank[8].action  = BBA_AUTOGAIN;
1643       bbank[9].name    = "Undo";
1644       bbank[9].action  = BBA_UNDO;
1645       bbank[9].raction = BBA_REDO;
1646       bbank[10].name   = "Optim";
1647       bbank[10].action = BBA_OPTIMISE;
1648       bbank[10].raction= BBA_OPTIMISE_MORE;
1649       bbank[11].name   = "About";
1650       bbank[11].action = BBA_ABOUT;
1651       bbank[12].name   = "Play Song";
1652       bbank[12].action = BBA_PLAYSONG;
1653       bbank[12].raction= BBA_CONTSONG;
1654       bbank[13].name   = "Play Pos";
1655       bbank[13].action = BBA_PLAYPOS;
1656       bbank[13].raction= BBA_CONTPOS;
1657       bbank[14].name   = "Stop";
1658       bbank[14].action = BBA_STOP;
1659       bbank[14].raction= BBA_STOP;
1660       bbank[15].name   = "Zap";
1661       bbank[15].action = BBA_ZAP;
1662       break;
1663 
1664 #ifdef __SDL_WRAPPER__
1665     case 1:
1666       bbank[0].name    = "Zap song";
1667       bbank[0].action  = BBA_ZAP_SONG;
1668       bbank[1].name    = "Zap Tracks";
1669       bbank[1].action  = BBA_ZAP_TRACKS;
1670       bbank[2].name    = "Zap Posns";
1671       bbank[2].action  = BBA_ZAP_POSNS;
1672       bbank[3].name    = "Zap Instrs";
1673       bbank[3].action  = BBA_ZAP_INSTRS;
1674       bbank[12].name   = "Zap All";
1675       bbank[12].action = BBA_ZAP_ALL;
1676       bbank[15].name   = "Cancel";
1677       bbank[15].action = BBA_BACK;
1678       break;
1679 #endif
1680   }
1681 
1682   set_font(&mainbm, FONT_PRP, FALSE);
1683 
1684   for( i=0; i<16; i++ )
1685   {
1686     if( bbank[i].name != NULL )
1687     {
1688 #ifndef __SDL_WRAPPER__
1689       bbank[i].xo = 40 - ( IGraphics->TextLength( &mainbm.rp, bbank[i].name, strlen( bbank[i].name ) ) >> 1 );
1690 #else
1691       int w, h;
1692       TTF_SizeText(mainbm.font, bbank[i].name, &w, &h);
1693       bbank[i].xo = 40 - (w/2);
1694 #endif
1695     }
1696   }
1697 }
1698 
gui_render_bbank_texts(struct buttonbank * bbnk,int32 nb)1699 void gui_render_bbank_texts( struct buttonbank *bbnk, int32 nb )
1700 {
1701   int32 i;
1702 
1703   set_font(&mainbm, FONT_PRP, FALSE);
1704   set_fpen(&mainbm, PAL_BTNSHADOW);
1705 
1706   for( i=0; i<nb; i++ )
1707   {
1708     if( bbnk[i].name != NULL )
1709     {
1710       printstr(&mainbm, bbnk[i].name, bbnk[i].x+bbnk[i].xo+1, bbnk[i].y+5);
1711     }
1712   }
1713 
1714   set_fpen(&mainbm, PAL_BTNTEXT);
1715 
1716   for( i=0; i<nb; i++ )
1717   {
1718     if( bbnk[i].name != NULL )
1719     {
1720       printstr(&mainbm, bbnk[i].name, bbnk[i].x+bbnk[i].xo, bbnk[i].y+4);
1721     }
1722   }
1723 }
1724 
gui_render_main_buttonbank(void)1725 void gui_render_main_buttonbank( void )
1726 {
1727   put_bitmap( BM_BUTBANKR, 256, 0, 4*80, 4*24 );
1728   gui_render_bbank_texts( &bbank[0], 16 );
1729 }
1730 
gui_render_track_buttonbank(void)1731 void gui_render_track_buttonbank( void )
1732 {
1733   put_bitmap( BM_TRKBANKR, 744, 120+200, 52, 12*23 );
1734   gui_render_bbank_texts( &tbank[0], 12 );
1735 }
1736 
gui_render_tabs(void)1737 void gui_render_tabs( void )
1738 {
1739   int32 ntabs, rtabs, tabw, tabsw, i, j, k, l, m, n, o, tabh;
1740   struct ahx_tune *at;
1741   const TEXT *tname;
1742 
1743   put_bitmap( BM_TAB_AREA, 0, 96, 800, 24 );
1744 
1745   tabh = 24;
1746   if( bitmaps[BM_TAB_MID].h >= 26 )
1747   {
1748     tabh = 26;
1749     l = PN_TRACKER;
1750     if( curtune )
1751       l = curtune->at_curpanel;
1752 
1753     switch( l )
1754     {
1755       case PN_INSED:
1756         put_bitmap( BM_BG_INSED, 0, 120, 800, 2 );
1757         break;
1758       default:
1759         put_bitmap( BM_BG_TRACKER, 0, 120, 800, 2 );
1760         break;
1761     }
1762   }
1763 
1764   for( i=0; i<8; i++ )
1765   {
1766     ttab[i].tune = NULL;
1767     gui_zap_zone( &zones[0], &numzones, MAX_ZONES, &ttab[i].zone );
1768   }
1769 
1770   IExec->ObtainSemaphore( rp_list_ss );
1771 
1772   ntabs = 0;
1773   at = (struct ahx_tune *)IExec->GetHead(rp_tunelist);
1774   while( at )
1775   {
1776     ntabs++;
1777     at = (struct ahx_tune *)IExec->GetSucc(&at->at_ln);
1778   }
1779 
1780   if( ntabs == 0 )
1781   {
1782     curtune = NULL;
1783     IExec->ReleaseSemaphore( rp_list_ss );
1784     return;
1785   }
1786 
1787   if( curtune == NULL )
1788     curtune = (struct ahx_tune *)IExec->GetHead(rp_tunelist);
1789 
1790   // Ensure phantom tab!
1791   rtabs = ntabs;
1792   if( rtabs < 2 ) rtabs = 2;
1793   if( rtabs > 8 ) rtabs = 8;
1794 
1795   // Space per tab
1796   tabsw = (800<<8) / rtabs;
1797 
1798   // Actual tab width
1799   tabw  = (tabsw>>8)&~15;
1800   if( tabw == (tabsw>>8) ) tabw -= 8;
1801 
1802   // Tab offset
1803   k = ((tabsw>>1)-(tabw<<7));
1804 
1805   set_font(&mainbm, FONT_PRP, FALSE);
1806 
1807   // Draw them!
1808   at = (struct ahx_tune *)IExec->GetHead(rp_tunelist);
1809   for( i=0, j=k; i<rtabs; i++, j+=tabsw )
1810   {
1811     if( i >= ntabs ) break;
1812 
1813     ttab[i].tune = at;
1814     ttab[i].zone = gui_add_zone( &zones[0], &numzones, MAX_ZONES, (j>>8), 96, tabw, 24 );
1815 
1816     if( at == curtune )
1817     {
1818       l = BM_TAB_LEFT;
1819       o = BM_TAB_TEXT;
1820       m = tabh;
1821     } else {
1822       l = BM_ITAB_LEFT;
1823       o = BM_ITAB_TEXT;
1824       m = 24;
1825     }
1826 
1827     tname = at->at_Name[0] ? at->at_Name : "[Untitled]";
1828 
1829 #ifndef __SDL_WRAPPER__
1830     n = IGraphics->TextLength( &mainbm.rp, tname, strlen( tname ) );
1831 #else
1832     TTF_SizeText(mainbm.font, tname, &n, &k);
1833 #endif
1834     if( !tabtextback ) o = l+1;
1835 
1836     put_bitmap( l+0, j>>8, 96, 20, m );
1837     for( k=0; k<(tabw-36); k+=32 )
1838     {
1839       put_bitmap( o, (j>>8)+20+k, 96, (tabw-36)-k < 32 ? (tabw-36)-k : 32, m );
1840       if( k > n ) o = l+1;
1841     }
1842     put_bitmap( l+2, (j>>8)+tabw-16, 96, 16, m );
1843 
1844     k = textfit(&mainbm, tname, tabw-32);
1845 
1846     if( tabtextshad )
1847     {
1848       set_fpen(&mainbm, PAL_TABSHADOW);
1849       printstrlen(&mainbm, tname, k, (j>>8)+25, 100);
1850     }
1851 
1852     set_fpen(&mainbm, PAL_TABTEXT);
1853     printstrlen(&mainbm, tname, k, (j>>8)+24, 99);
1854     at = (struct ahx_tune *)IExec->GetSucc(&at->at_ln);
1855   }
1856 
1857   IExec->ReleaseSemaphore( rp_list_ss );
1858 }
1859 
gui_render_wavemeter(void)1860 void gui_render_wavemeter( void )
1861 {
1862   int32 i, v, off, delta;
1863   int16 *ba;
1864 
1865   set_fpen(&bitmaps[BM_WAVEMETERS], PAL_BACK);
1866   fillrect_xy(&bitmaps[BM_WAVEMETERS], 9,  7, 181+9, 37+ 7);
1867   fillrect_xy(&bitmaps[BM_WAVEMETERS], 9, 49, 181+9, 37+49);
1868 
1869   set_fpen(&bitmaps[BM_WAVEMETERS], PAL_WAVEMETER);
1870 
1871 #ifndef __SDL_WRAPPER__
1872   ba = (int16 *)rp_audiobuffer[0];
1873 #else
1874   ba = rp_audiobuffer;
1875 #endif
1876   delta = rp_audiobuflen / 728;
1877   if( delta == 0 ) delta = 1;
1878   delta <<= 1;
1879 
1880   for( i=9, off=0; i<(9+182); i++, off += delta )
1881   {
1882     v = (ba[off] >> 10) + 16 + 10;
1883     if( v < (0+10) ) v = 0+10;
1884     if( v > (31+10) ) v = 31+10;
1885 #ifndef __SDL_WRAPPER__
1886     if( i == 9 )
1887       IGraphics->Move( &bitmaps[BM_WAVEMETERS].rp, 9, v );
1888     else
1889       IGraphics->Draw( &bitmaps[BM_WAVEMETERS].rp, i, v );
1890 #else
1891      fillrect_xy(&bitmaps[BM_WAVEMETERS], i, v, i, v);
1892 #endif
1893   }
1894 
1895   ba++;
1896 
1897   for( i=9, off=0; i<(9+182); i++, off += delta )
1898   {
1899     v = (ba[off] >> 10) + 16 + 52;
1900     if( v < (0+52) ) v = 0+52;
1901     if( v > (31+52) ) v = 31+52;
1902 #ifndef __SDL_WRAPPER__
1903     if( i == 9 )
1904       IGraphics->Move( &bitmaps[BM_WAVEMETERS].rp, 9, v );
1905     else
1906       IGraphics->Draw( &bitmaps[BM_WAVEMETERS].rp, i, v );
1907 #else
1908      fillrect_xy(&bitmaps[BM_WAVEMETERS], i, v, i, v);
1909 #endif
1910   }
1911   put_bitmap( BM_WAVEMETERS, 576, 0, 200, 96 );
1912 }
1913 
gui_render_vumeters(void)1914 void gui_render_vumeters( void )
1915 {
1916   int32 lch, dch, v, i;
1917 
1918   if( curtune == NULL ) return;
1919 
1920   if( curtune->at_curpanel != PN_TRACKER )
1921     return;
1922 
1923   dch = curtune->at_Channels;
1924   if( dch > 6 ) dch = 6;
1925   lch = curtune->at_curlch;
1926 
1927   for( i=0; i<dch; i++ )
1928   {
1929     v = curtune->at_Voices[i+lch].vc_VUMeter >> 7;
1930     if( v > 64 ) v = 64;
1931 
1932     if( ( vum_needclr ) && ( v < vum_last[i+lch] ) && ( v < 64 ) )
1933     {
1934 #ifndef __SDL_WRAPPER__
1935       IGraphics->BltBitMapRastPort( bitmaps[BM_TRACKED].bm, 64+i*120, 64, mainwin->RPort, TRACKED_X+64+i*120, TRACKED_Y+64, 32, 64-v, 0x0C0 );
1936 #else
1937       SDL_Rect srect = { .x = 64+i*120, .y = 64, .w = 32, .h = 64-v };
1938       SDL_Rect drect = { .x = TRACKED_X+64+i*120, .y = TRACKED_Y+64, .w = 32, .h = 64-v };
1939       SDL_BlitSurface( bitmaps[BM_TRACKED].srf, &srect, ssrf, &drect );
1940       needaflip = TRUE;
1941 #endif
1942     }
1943 
1944     if( v > 0 )
1945       put_bitmap( BM_VUMETER, TRACKED_X+64+i*120, (TRACKED_Y+128)-v, 32, v );
1946 
1947     vum_last[i+lch] = v;
1948   }
1949 
1950   vum_needclr = TRUE;
1951 }
1952 
gui_render_tracked(BOOL force)1953 void gui_render_tracked( BOOL force )
1954 {
1955   int16 posnr=0, notenr=0, trklen=0, trkmax=0;
1956   struct ahx_tune *at;
1957   struct ahx_step *stp;
1958   int32 i, j, k, l, bw, lch, dch, ech;
1959   BOOL needrestore, hrestore;
1960   TEXT pbuf[256];
1961 
1962   i = PN_TRACKER;
1963   if( curtune )
1964     i = curtune->at_curpanel;
1965 
1966   if( i != PN_TRACKER ) return;
1967 
1968   bw = TRACKED_W;
1969   lch = dch = 0;
1970 
1971   at = curtune;
1972   if( at )
1973   {
1974     if( at->at_cbmarktrack != -1 )
1975     {
1976       if( ( at->at_doing == D_EDITING ) || ( at->at_doing == D_IDLE ) )
1977       {
1978         // Do the full-on draw
1979         force = TRUE;
1980         at->at_cbmarkcurnote = at->at_NoteNr;
1981         at->at_cbmarkcurx    = at->at_tracked_curs%9;
1982 
1983         if( at->at_cbmarkmarknote > at->at_cbmarkcurnote )
1984         {
1985           at->at_cbmarkstartnote = at->at_cbmarkcurnote;
1986           at->at_cbmarkendnote   = at->at_cbmarkmarknote;
1987         } else {
1988           at->at_cbmarkstartnote = at->at_cbmarkmarknote;
1989           at->at_cbmarkendnote   = at->at_cbmarkcurnote;
1990         }
1991 
1992         i = at->at_tracked_curs/9+at->at_curlch;
1993         j = at->at_Positions[at->at_PosNr].pos_Track[i];
1994 
1995         if( j == at->at_cbmarktrack )
1996         {
1997           if( at->at_cbmarkmarkx > at->at_cbmarkcurx )
1998           {
1999             at->at_cbmarkleftx  = at->at_cbmarkcurx;
2000             at->at_cbmarkrightx = at->at_cbmarkmarkx;
2001           } else {
2002             at->at_cbmarkleftx  = at->at_cbmarkmarkx;
2003             at->at_cbmarkrightx = at->at_cbmarkcurx;
2004           }
2005         }
2006 
2007         at->at_cbmarkbits = 0;
2008         if( at->at_cbmarkleftx < 3 ) at->at_cbmarkbits |= CBF_NOTES;
2009         if( ( at->at_cbmarkleftx < 6 ) && ( at->at_cbmarkrightx > 2 ) ) at->at_cbmarkbits |= CBF_CMD1;
2010         if( at->at_cbmarkrightx > 5 ) at->at_cbmarkbits |= CBF_CMD2;
2011       } else {
2012         // Cancel if not editing or idle
2013         at->at_cbmarktrack = -1;
2014       }
2015     }
2016 
2017     posnr  = at->at_PosNr;
2018     notenr = at->at_NoteNr;
2019     trklen = at->at_TrackLength;
2020     trkmax = trklen-1;
2021     dch    = at->at_Channels;
2022     if( dch > 6 ) dch = 6;
2023     lch    = at->at_curlch;
2024   }
2025 
2026   if( force == FALSE )
2027   {
2028     if( ( at     == trked_lasttune ) &&
2029         ( posnr  == trked_lastposnr ) &&
2030         ( notenr == trked_lastnotenr ) &&
2031         ( lch    == trked_lastlchan ) &&
2032         ( dch    == trked_lastchans ) )
2033       return;
2034   }
2035 
2036   ech = dch + lch;
2037 
2038   // Optimise for scrolling?
2039   if( ( at == trked_lasttune ) &&
2040       ( posnr == trked_lastposnr ) &&
2041       ( notenr == trked_lastnotenr+1 ) &&
2042       ( lch == trked_lastlchan ) &&
2043       ( dch == trked_lastchans ) &&
2044       ( force == FALSE ) &&
2045       ( at != NULL ) )
2046   {
2047     bw = (3*8)+(dch*15*8)-1;
2048     if( bw > TRACKED_W ) bw = TRACKED_W;
2049 #ifndef __SDL_WRAPPER__
2050     IGraphics->ScrollRaster( &bitmaps[BM_TRACKED].rp, 0, 16, 0, 0, bw, TRACKED_MY );
2051 #else
2052     {
2053       SDL_Rect srect = { .x = 0, .y = 16, .w = bw, .h = TRACKED_H-16 };
2054       SDL_Rect drect = { .x = 0, .y = 0, .w = bw, .h = TRACKED_H-16 };
2055       SDL_BlitSurface(bitmaps[BM_TRACKED].srf, &srect, bitmaps[BM_TRACKED].srf, &drect);
2056     }
2057 #endif
2058 
2059     set_fpen(&bitmaps[BM_TRACKED], PAL_BACK);
2060     fillrect_xy(&bitmaps[BM_TRACKED], 0, 256, TRACKED_MX, TRACKED_MY );
2061     fillrect_xy(&bitmaps[BM_TRACKED], 0, 7*16-2, TRACKED_MX, 7*16-1 );
2062 //    IGraphics->Move( &bitmaps[BM_TRACKED].rp, 0, 7*16-1 );
2063 //    IGraphics->Draw( &bitmaps[BM_TRACKED].rp, bw, 7*16-1 );
2064 
2065     hrestore = FALSE;
2066     set_fpen(&bitmaps[BM_TRACKED], PAL_TEXT);
2067     for( i=notenr-1, j=(7*16); i<notenr+3; i++, j+=16 )
2068     {
2069       if( i == notenr+2 )
2070       {
2071         i = notenr+8;
2072         j = (16*16);
2073       }
2074       if( i == notenr )
2075         set_bpen(&bitmaps[BM_TRACKED], PAL_BARMID);
2076       if( i == notenr+1 )
2077         set_bpen(&bitmaps[BM_TRACKED], PAL_BACK);
2078 
2079       if( ( i == at->at_rempos[0] ) ||
2080           ( i == at->at_rempos[1] ) ||
2081           ( i == at->at_rempos[2] ) ||
2082           ( i == at->at_rempos[3] ) ||
2083           ( i == at->at_rempos[4] ) )
2084       {
2085         set_fpen(&bitmaps[BM_TRACKED], PAL_FKEYHIGHLIGHT);
2086         hrestore = TRUE;
2087       } else {
2088         if( hrestore )
2089         {
2090           set_fpen(&bitmaps[BM_TRACKED], PAL_TEXT);
2091           hrestore = FALSE;
2092         }
2093       }
2094 
2095       if( ( i >= 0 ) && ( i < trklen ) )
2096       {
2097         sprintf( pbuf, "%02d ", (int)i );
2098         for( k=lch, l=0; k<ech; k++, l++ )
2099         {
2100           stp = &at->at_Tracks[at->at_Positions[posnr].pos_Track[k]&0xff][i];
2101           if( stp->stp_Instrument )
2102           {
2103             sprintf( &pbuf[l*15+3], "%s %02d %1X%02X %1X%02X ",
2104               notenames[stp->stp_Note],
2105               stp->stp_Instrument,
2106               stp->stp_FX,
2107               stp->stp_FXParam&0xff,
2108               stp->stp_FXb,
2109               stp->stp_FXbParam&0xff );
2110           } else {
2111             sprintf( &pbuf[l*15+3], "%s    %1X%02X %1X%02X ",
2112               notenames[stp->stp_Note],
2113               stp->stp_FX,
2114               stp->stp_FXParam&0xff,
2115               stp->stp_FXb,
2116               stp->stp_FXbParam&0xff );
2117           }
2118 
2119           if( pref_blankzeros )
2120           {
2121             if( ( stp->stp_FX == 0 ) && ( stp->stp_FXParam == 0 ) )
2122             {
2123               pbuf[l*15+10] = ' ';
2124               pbuf[l*15+11] = ' ';
2125               pbuf[l*15+12] = ' ';
2126             }
2127 
2128             if( ( stp->stp_FXb == 0 ) && ( stp->stp_FXbParam == 0 ) )
2129             {
2130               pbuf[l*15+14] = ' ';
2131               pbuf[l*15+15] = ' ';
2132               pbuf[l*15+16] = ' ';
2133             }
2134           }
2135         }
2136         printstr(&bitmaps[BM_TRACKED], pbuf, 0, j);
2137       }
2138     }
2139 
2140   } else {
2141 
2142     // Not optimised for scrolling
2143 
2144     if( ( !at ) || ( force ) )
2145     {
2146       set_fpen(&bitmaps[BM_TRACKED], PAL_BACK);
2147       fillrect_xy(&bitmaps[BM_TRACKED], 0, 0, TRACKED_MX, TRACKED_MY);
2148       set_fpen(&bitmaps[BM_TRACKED], PAL_BARMID);
2149       fillrect_xy(&bitmaps[BM_TRACKED], 0, 8*16, TRACKED_MX, 8*16+15);
2150     }
2151 
2152     if( at )
2153     {
2154       if( ( force ) || ( lch != trked_lastlchan ) || ( posnr != trked_lastposnr ) )
2155       {
2156         set_font(&bitmaps[BM_TRACKBAR], FONT_PRP, FALSE);
2157         bm_to_bm(&bitmaps[BM_BG_TRACKER], 20+TRACKED_X, TRACKED_Y-142, &bitmaps[BM_TRACKBAR], 0, 0, 768, 19);
2158 
2159         for( j=0, k=lch, l=0; l<6; j+=15*8, k++, l++ )
2160         {
2161           if( k < ech )
2162           {
2163             sprintf( pbuf, "Track %d", (int)k+1 );
2164             set_fpen(&bitmaps[BM_TRACKBAR], PAL_BTNSHADOW);
2165             printstr(&bitmaps[BM_TRACKBAR], pbuf, j+1, 2);
2166             set_fpen(&bitmaps[BM_TRACKBAR], PAL_BTNTEXT);
2167             printstr(&bitmaps[BM_TRACKBAR], pbuf, j, 1);
2168           }
2169         }
2170 
2171         set_font(&bitmaps[BM_TRACKBAR], FONT_FIX, TRUE);
2172         set_pens(&bitmaps[BM_TRACKBAR], PAL_TEXT, PAL_BACK);
2173         for( j=11*8-2, k=lch, l=0; l<6; j+=15*8, k++, l++ )
2174         {
2175           if( k < ech )
2176           {
2177             if( at->at_Voices[k].vc_SetTrackOn )
2178               bm_to_bm(&bitmaps[BM_CHANMUTE], 0, 0, &bitmaps[BM_TRACKBAR], j-20, 0, 14, 19);
2179             else
2180               bm_to_bm(&bitmaps[BM_CHANMUTE], 0, 19, &bitmaps[BM_TRACKBAR], j-20, 0, 14, 19);
2181             sprintf( pbuf, "%03d", at->at_Positions[posnr].pos_Track[k] );
2182             printstr(&bitmaps[BM_TRACKBAR], pbuf, j, 1);
2183           }
2184         }
2185         put_bitmap( BM_TRACKBAR, 20+TRACKED_X, TRACKED_Y-22, TRACKED_W-24, 19 );
2186       }
2187 
2188       if( notenr < 8 )
2189       {
2190         set_fpen(&bitmaps[BM_TRACKED], PAL_BACK);
2191         fillrect_xy(&bitmaps[BM_TRACKED], 0, 0, TRACKED_MX, ((8-notenr)*16)-1);
2192       }
2193 
2194       if( notenr > trkmax-8 )
2195       {
2196         set_fpen(&bitmaps[BM_TRACKED], PAL_BACK);
2197         fillrect_xy(&bitmaps[BM_TRACKED], 0, ((trklen-notenr)+8)*16, TRACKED_MX, TRACKED_MY);
2198       }
2199 
2200       hrestore = FALSE;
2201 
2202       set_fpen(&bitmaps[BM_TRACKED], PAL_TEXT);
2203       for( i=notenr-8, j=0; i<notenr+9; i++, j+=16 )
2204       {
2205         if( i == notenr )
2206           set_bpen(&bitmaps[BM_TRACKED], PAL_BARMID);
2207         if( i == notenr+1 )
2208           set_bpen(&bitmaps[BM_TRACKED], PAL_BACK);
2209 
2210         if( ( i == at->at_rempos[0] ) ||
2211             ( i == at->at_rempos[1] ) ||
2212             ( i == at->at_rempos[2] ) ||
2213             ( i == at->at_rempos[3] ) ||
2214             ( i == at->at_rempos[4] ) )
2215         {
2216           set_fpen(&bitmaps[BM_TRACKED], PAL_FKEYHIGHLIGHT);
2217           hrestore = TRUE;
2218         } else {
2219           if( hrestore )
2220           {
2221             set_fpen(&bitmaps[BM_TRACKED], PAL_TEXT);
2222             hrestore = FALSE;
2223           }
2224         }
2225 
2226         if( ( i >= 0 ) && ( i < trklen ) )
2227         {
2228           sprintf( pbuf, "%02d ", (int)i );
2229           for( k=lch, l=0; k<ech; k++, l++ )
2230           {
2231             stp = &at->at_Tracks[at->at_Positions[posnr].pos_Track[k]&0xff][i];
2232             if( stp->stp_Instrument )
2233             {
2234               sprintf( &pbuf[l*15+3], "%s %02d %1X%02X %1X%02X ",
2235                 notenames[stp->stp_Note],
2236                 stp->stp_Instrument,
2237                 stp->stp_FX,
2238                 stp->stp_FXParam&0xff,
2239                 stp->stp_FXb,
2240                 stp->stp_FXbParam&0xff );
2241             } else {
2242               sprintf( &pbuf[l*15+3], "%s    %1X%02X %1X%02X ",
2243                 notenames[stp->stp_Note],
2244                 stp->stp_FX,
2245                 stp->stp_FXParam&0xff,
2246                 stp->stp_FXb,
2247                 stp->stp_FXbParam&0xff );
2248             }
2249 
2250             if( pref_blankzeros )
2251             {
2252               if( ( stp->stp_FX == 0 ) && ( stp->stp_FXParam == 0 ) )
2253               {
2254                 pbuf[l*15+10] = ' ';
2255                 pbuf[l*15+11] = ' ';
2256                 pbuf[l*15+12] = ' ';
2257               }
2258 
2259               if( ( stp->stp_FXb == 0 ) && ( stp->stp_FXbParam == 0 ) )
2260               {
2261                 pbuf[l*15+14] = ' ';
2262                 pbuf[l*15+15] = ' ';
2263                 pbuf[l*15+16] = ' ';
2264               }
2265             }
2266           }
2267           printstr(&bitmaps[BM_TRACKED], pbuf, 0, j);
2268 
2269           if( at->at_cbmarktrack != -1 )
2270           {
2271             needrestore = FALSE;
2272 
2273             l = at->at_tracked_curs/9;
2274             k = l+lch;
2275 
2276             // Render any marked blocks
2277             if( ( k >= lch ) && ( k<ech ) )
2278             {
2279               if( ( i >= at->at_cbmarkstartnote ) &&
2280                   ( i <= at->at_cbmarkendnote ) &&
2281                   ( at->at_Positions[posnr].pos_Track[k] == at->at_cbmarktrack ) )
2282               {
2283                 stp = &at->at_Tracks[at->at_Positions[posnr].pos_Track[k]&0xff][i];
2284 
2285                 if( needrestore == FALSE )
2286                 {
2287                   set_pens(&bitmaps[BM_TRACKED], PAL_BACK, PAL_TEXT);
2288                   needrestore = TRUE;
2289                 }
2290 
2291                 if( stp->stp_Instrument )
2292                 {
2293                   sprintf( pbuf, "%s %02d %1X%02X %1X%02X",
2294                     notenames[stp->stp_Note],
2295                     stp->stp_Instrument,
2296                     stp->stp_FX,
2297                     stp->stp_FXParam&0xff,
2298                     stp->stp_FXb,
2299                     stp->stp_FXbParam&0xff );
2300                 } else {
2301                   sprintf( pbuf, "%s    %1X%02X %1X%02X",
2302                     notenames[stp->stp_Note],
2303                     stp->stp_FX,
2304                     stp->stp_FXParam&0xff,
2305                     stp->stp_FXb,
2306                     stp->stp_FXbParam&0xff );
2307                 }
2308 
2309                 switch( at->at_cbmarkbits )
2310                 {
2311                   case CBF_NOTES:
2312                     printstrlen(&bitmaps[BM_TRACKED], pbuf, 6, 24+(l*120), j );
2313                     break;
2314                   case CBF_NOTES|CBF_CMD1:
2315                     printstrlen(&bitmaps[BM_TRACKED], pbuf, 10, 24+(l*120), j );
2316                     break;
2317                   case CBF_NOTES|CBF_CMD1|CBF_CMD2:  // everything
2318                     printstr(&bitmaps[BM_TRACKED], pbuf, 24+(l*120), j );
2319                     break;
2320                   case CBF_CMD1:
2321                     printstrlen(&bitmaps[BM_TRACKED], &pbuf[7], 3, 24+(7*8)+(l*120), j );
2322                     break;
2323                   case CBF_CMD1|CBF_CMD2:
2324                     printstrlen(&bitmaps[BM_TRACKED], &pbuf[7], 7, 24+(7*8)+(l*120), j );
2325                     break;
2326                   case CBF_CMD2:
2327                     printstrlen(&bitmaps[BM_TRACKED], &pbuf[11], 3, 24+(11*8)+(l*120), j );
2328                     break;
2329                 }
2330               }
2331             }
2332             if( needrestore )
2333             {
2334               set_pens(&bitmaps[BM_TRACKED], PAL_TEXT, PAL_BACK);
2335             }
2336           }
2337         }
2338       }
2339     }
2340   }
2341 
2342   trked_lasttune   = at;
2343   trked_lastposnr  = posnr;
2344   trked_lastnotenr = notenr;
2345   trked_lastchans  = dch;
2346   trked_lastlchan  = lch;
2347 
2348   set_fpen(&bitmaps[BM_TRACKED], PAL_BARMID);
2349   for( i=0; i<6*120; i+=120 )
2350   {
2351     fillrect_xy(&bitmaps[BM_TRACKED], i+24+28, 0, i+24+28, TRACKED_MY);
2352     fillrect_xy(&bitmaps[BM_TRACKED], i+24+52, 0, i+24+52, TRACKED_MY);
2353     fillrect_xy(&bitmaps[BM_TRACKED], i+24+84, 0, i+24+84, TRACKED_MY);
2354   }
2355 
2356   set_fpen(&bitmaps[BM_TRACKED], PAL_BARLIGHT);
2357   fillrect_xy(&bitmaps[BM_TRACKED], 0, 8*16-1, TRACKED_MX, 8*16-1);
2358   set_fpen(&bitmaps[BM_TRACKED], PAL_BARDARK);
2359   fillrect_xy(&bitmaps[BM_TRACKED], 0, 9*16-1, TRACKED_MX, 9*16-1);
2360   set_fpen(&bitmaps[BM_TRACKED], PAL_TEXT);
2361   fillrect_xy(&bitmaps[BM_TRACKED], 20, 0, 20, TRACKED_MY);
2362 
2363   for( i=120; i<6*120; i+=120 )
2364   {
2365     fillrect_xy(&bitmaps[BM_TRACKED], 20+i, 0, 20+i, TRACKED_MY);
2366   }
2367 
2368   if( at->at_editing == E_TRACK )
2369   {
2370     int32 cx, cy, mx, my;
2371 
2372     if( at->at_doing == D_EDITING )
2373       set_fpen(&bitmaps[BM_TRACKED], PAL_CURSEDIT);
2374     else
2375       set_fpen(&bitmaps[BM_TRACKED], PAL_CURSNORM);
2376 
2377     cx = tracked_xoff[at->at_tracked_curs]-2;
2378     cy = 8*16-2;
2379     mx = cx+8+3;
2380     my = cy+16+3;
2381 
2382     if( ( at->at_tracked_curs % 9 ) == 0 )
2383       mx = cx+24+3;
2384 
2385     fillrect_xy(&bitmaps[BM_TRACKED], cx, cy, mx, cy+1);
2386     fillrect_xy(&bitmaps[BM_TRACKED], cx, my-1, mx, my);
2387     fillrect_xy(&bitmaps[BM_TRACKED], cx, cy, cx+1, my);
2388     fillrect_xy(&bitmaps[BM_TRACKED], mx-1, cy, mx, my);
2389   }
2390 
2391   put_bitmap( BM_TRACKED, TRACKED_X, TRACKED_Y, bw, TRACKED_H );
2392   vum_needclr = FALSE;
2393 }
2394 
gui_render_inslist(BOOL force)2395 void gui_render_inslist( BOOL force )
2396 {
2397   struct ahx_tune *at;
2398   struct ahx_instrument *in;
2399   int16 curi;
2400   int32 i, j, k;
2401   TEXT tmp[32];
2402 
2403   curi = 0;
2404 
2405   at = curtune;
2406   if( at )
2407   {
2408     if( at->at_curpanel != PN_TRACKER )
2409       return;
2410 
2411     curi = at->at_curins;
2412   }
2413 
2414   if( ( insls_lastcuri == curi ) &&
2415       ( insls_lasttune == at ) &&
2416       ( insls_lasttopi == at->at_topins ) &&
2417       ( force == FALSE ) )
2418     return;
2419 
2420   set_fpen(&bitmaps[BM_INSLIST], PAL_BACK);
2421   fillrect_xy(&bitmaps[BM_INSLIST], 0, 0, INSLIST_MX, INSLIST_MY);
2422 
2423   if( at )
2424   {
2425     if( curi < at->at_topins )     at->at_topins = curi;
2426     if( curi > (at->at_topins+8) ) at->at_topins = curi-8;
2427 
2428     if( at->at_topins < 1 ) at->at_topins = 1;
2429 
2430     set_pens(&bitmaps[BM_INSLIST], PAL_TEXT, PAL_BACK);
2431     for( i=0, j=at->at_topins; i<9; i++, j++ )
2432     {
2433       sprintf( tmp, "%02d                      ", (int)j );
2434       in = &at->at_Instruments[j];
2435 
2436       for( k=0; k<21; k++ )
2437       {
2438         if( in->ins_Name[k] == 0 ) break;
2439         tmp[k+3] = in->ins_Name[k];
2440       }
2441 
2442       if( j == curi )
2443         set_bpen(&bitmaps[BM_INSLIST], PAL_BARMID);
2444       if( j == curi+1 )
2445         set_bpen(&bitmaps[BM_INSLIST], PAL_BACK);
2446 
2447       printstrlen(&bitmaps[BM_INSLIST], tmp, 24, 0, i*14+5);
2448     }
2449 
2450     if( curi >= at->at_topins )
2451     {
2452       k = (curi-at->at_topins)*14+5;
2453       set_fpen(&bitmaps[BM_INSLIST], PAL_BARLIGHT);
2454       fillrect_xy(&bitmaps[BM_INSLIST], 0, k-1, INSLIST_MX, k-1);
2455       set_fpen(&bitmaps[BM_INSLIST], PAL_BARDARK);
2456       fillrect_xy(&bitmaps[BM_INSLIST], 0, k+14, INSLIST_MX, k+14);
2457     }
2458 
2459     set_fpen(&bitmaps[BM_INSLIST], PAL_TEXT);
2460     fillrect_xy(&bitmaps[BM_INSLIST], 17, 0, 17, INSLIST_MY);
2461   }
2462 
2463   put_bitmap( BM_INSLIST, INSLIST_X, INSLIST_Y, INSLIST_W, INSLIST_H );
2464   insls_lastcuri = curi;
2465   insls_lasttune = at;
2466   insls_lasttopi = at->at_topins;
2467 }
2468 
gui_render_posed(BOOL force)2469 void gui_render_posed( BOOL force )
2470 {
2471   struct ahx_tune *at;
2472   int16 posnr=0;
2473   int32 i, j, k, l, m, lch=0, dch, ech;
2474   TEXT pbuf[256];
2475 
2476   at = curtune;
2477   dch = 0;
2478   if( at )
2479   {
2480     if( at->at_curpanel != PN_TRACKER )
2481       return;
2482 
2483     if( at->at_NextPosNr != -1 )
2484       posnr = at->at_NextPosNr;
2485     else
2486       posnr = at->at_PosNr;
2487     lch = at->at_curlch;
2488     dch = at->at_Channels;
2489     if( dch > 6 ) dch = 6;
2490   }
2491 
2492   ech = lch + dch;
2493 
2494   if( force == FALSE )
2495   {
2496     if( ( at == posed_lasttune ) &&
2497         ( posnr == posed_lastposnr ) &&
2498         ( lch == posed_lastlchan ) &&
2499         ( dch == posed_lastchans ) )
2500       return;
2501   }
2502 
2503   if( posed_lastposnr != posnr )
2504   {
2505     trk_nb[NB_POSNR].cnum = posnr;
2506     gui_render_nbox( at, PN_TRACKER, &trk_nb[NB_POSNR] );
2507   }
2508 
2509   posed_lasttune  = at;
2510   posed_lastposnr = posnr;
2511   posed_lastlchan = lch;
2512   posed_lastchans = dch;
2513 
2514   if( ( !at ) || ( force ) )
2515   {
2516     set_fpen(&bitmaps[BM_POSED], PAL_BACK);
2517     fillrect_xy(&bitmaps[BM_POSED], 0, 0, POSED_MX, POSED_MY);
2518     set_fpen(&bitmaps[BM_POSED], PAL_BARMID);
2519     fillrect_xy( &bitmaps[BM_POSED], 0, 3*14, POSED_MX, 3*14+13 );
2520   }
2521 
2522   if( at )
2523   {
2524     if( posnr < 3 )
2525     {
2526       set_fpen(&bitmaps[BM_POSED], PAL_BACK);
2527       fillrect_xy( &bitmaps[BM_POSED], 0, 0, POSED_MX, ((3-posnr)*14)-1 );
2528     }
2529 
2530     if( posnr > 996 )
2531     {
2532       set_fpen(&bitmaps[BM_POSED], PAL_BACK);
2533       fillrect_xy( &bitmaps[BM_POSED], 0, (1003-posnr)*14, POSED_MX, POSED_MY );
2534     }
2535 
2536     set_fpen(&bitmaps[BM_POSED], PAL_TEXT);
2537     for( i=posnr-3, j=0; i<posnr+4; i++, j+=14 )
2538     {
2539       if( i == posnr )
2540         set_bpen(&bitmaps[BM_POSED], PAL_BARMID);
2541       if( i == posnr+1 )
2542         set_bpen(&bitmaps[BM_POSED], PAL_BACK);
2543 
2544       if( ( i >= 0 ) && ( i < 1000 ) )
2545       {
2546         sprintf( pbuf, "%03d ", (int)i );
2547         for( k=lch, l=0; k<ech; k++, l++ )
2548           sprintf( &pbuf[l*7+4], "%03d %02X ",
2549             at->at_Positions[i].pos_Track[k]&0xff,
2550             at->at_Positions[i].pos_Transpose[k]&0xff );
2551         printstr(&bitmaps[BM_POSED], pbuf, 0, j);
2552       }
2553     }
2554 
2555     // Any marked areas?
2556     if( at->at_cbpmarkmarklft != -1 )
2557     {
2558       BOOL showit;
2559 
2560       at->at_cbpmarktop    = at->at_cbpmarkmarkpos;
2561       at->at_cbpmarklft    = at->at_cbpmarkmarklft;
2562       at->at_cbpmarkbot    = at->at_PosNr;
2563       at->at_cbpmarkrgt    = (((at->at_posed_curs/5)+lch)<<1)|((at->at_posed_curs%5)>2?1:0);
2564 
2565       if( at->at_cbpmarktop > at->at_cbpmarkbot )
2566       {
2567         i                 = at->at_cbpmarktop;
2568         at->at_cbpmarktop = at->at_cbpmarkbot;
2569         at->at_cbpmarkbot = i;
2570       }
2571 
2572       if( at->at_cbpmarklft > at->at_cbpmarkrgt )
2573       {
2574         i                 = at->at_cbpmarklft;
2575         at->at_cbpmarklft = at->at_cbpmarkrgt;
2576         at->at_cbpmarkrgt = i;
2577       }
2578 
2579       at->at_cbpmarklftcol = at->at_cbpmarklft & 1;
2580       at->at_cbpmarkrgtcol = at->at_cbpmarkrgt & 1;
2581       at->at_cbpmarklft    >>= 1;
2582       at->at_cbpmarkrgt    >>= 1;
2583 
2584       showit = TRUE;
2585       if( ( at->at_cbpmarkrgt < lch ) ||
2586           ( at->at_cbpmarklft >= ech ) ||
2587           ( at->at_cbpmarkbot < (posnr-3) ) ||
2588           ( at->at_cbpmarktop > (posnr+3) ) )
2589         showit = FALSE;
2590 
2591       if( showit )
2592       {
2593         int32 kl, kr, it, ib;
2594 
2595         kl = at->at_cbpmarklft>lch ? at->at_cbpmarklft : lch;
2596         kr = at->at_cbpmarkrgt<(ech-1) ? at->at_cbpmarkrgt : (ech-1);
2597         it = at->at_cbpmarktop>(posnr-3) ? at->at_cbpmarktop : (posnr-3);
2598         ib = at->at_cbpmarkbot<(posnr+3) ? at->at_cbpmarkbot : (posnr+3);
2599 
2600         set_pens(&bitmaps[BM_POSED], PAL_BACK, PAL_TEXT);
2601 
2602         pbuf[0]=0;
2603 
2604         // Nice! or... more accurately Confusing!
2605         for( i=it, j=14*(it-(posnr-3));
2606              i<=ib;
2607              i++, j+=14 )
2608         {
2609 
2610           for( m=0, k=kl, l=0; k<=kr; k++, l++ )
2611           {
2612             if( ( k>kl ) || ( at->at_cbpmarklftcol == 0 ) )
2613             {
2614               sprintf( &pbuf[m], "%03d ", at->at_Positions[i].pos_Track[k]&0xff );
2615               m+=4;
2616             }
2617             if( ( k<kr ) || ( at->at_cbpmarkrgtcol != 0 ) )
2618             {
2619               sprintf( &pbuf[m], "%02X ", at->at_Positions[i].pos_Transpose[k]&0xff );
2620               m+=3;
2621             }
2622           }
2623           pbuf[m-1] = 0;
2624           printstr(&bitmaps[BM_POSED], pbuf, ((kl-lch)*49)+(at->at_cbpmarklftcol*28)+28, j);
2625         }
2626       }
2627     }
2628 
2629     set_pens(&bitmaps[BM_POSED], PAL_POSEDCHIND, PAL_BARMID);
2630     for( k=lch, l=0; k<ech; k++, l++ )
2631     {
2632       sprintf( pbuf, "%d ", (int)k+1 );
2633       printstr(&bitmaps[BM_POSED], pbuf, l*49+25, 0);
2634     }
2635     set_bpen(&bitmaps[BM_POSED], PAL_BACK);
2636   }
2637 
2638   set_fpen(&bitmaps[BM_POSED], PAL_BARLIGHT);
2639   fillrect_xy(&bitmaps[BM_POSED], 0, 3*14-1, POSED_MX, 3*14-1);
2640   set_fpen(&bitmaps[BM_POSED], PAL_BARDARK);
2641   fillrect_xy(&bitmaps[BM_POSED], 0, 4*14, POSED_MX, 4*14);
2642 
2643   set_fpen(&bitmaps[BM_POSED], PAL_TEXT);
2644   fillrect_xy(&bitmaps[BM_POSED], 24, 0, 24, POSED_MY);
2645 
2646   for( i=1; i<6; i++ )
2647   {
2648     fillrect_xy(&bitmaps[BM_POSED], 24+i*49, 0, 24+i*49, POSED_MY);
2649   }
2650 
2651   if( at->at_editing == E_POS )
2652   {
2653     int32 cx, cy, mx, my;
2654 
2655     cx = posed_xoff[at->at_posed_curs]-2;
2656     cy = 3*14-2;
2657     mx = cx+7+3;
2658     my = cy+14+3;
2659 
2660     fillrect_xy(&bitmaps[BM_POSED], cx, cy, mx, cy+1 );
2661     fillrect_xy(&bitmaps[BM_POSED], cx, my-1, mx, my );
2662     fillrect_xy(&bitmaps[BM_POSED], cx, cy, cx+1, my );
2663     fillrect_xy(&bitmaps[BM_POSED], mx-1, cy, mx, my );
2664   }
2665 
2666   put_bitmap( BM_POSED, POSED_X, POSED_Y, POSED_W, POSED_H );
2667 }
2668 
gui_render_tracker(BOOL force)2669 void gui_render_tracker( BOOL force )
2670 {
2671   int32 panel, i;
2672 
2673   if( curtune == NULL )
2674     panel = PN_TRACKER;
2675   else
2676     panel = curtune->at_curpanel;
2677 
2678   if( panel != PN_TRACKER ) return;
2679 
2680   gui_render_posed( force );
2681   gui_render_tracked( force );
2682   gui_render_inslist( force );
2683   gui_set_various_things( curtune );
2684   for( i=0; i<TB_END; i++ )
2685     gui_render_tbox( &mainbm, &tbx[i] );
2686 }
2687 
gui_render_timer(BOOL force)2688 void gui_render_timer( BOOL force )
2689 {
2690   TEXT tbuf[128];
2691   if( curtune == NULL ) return;
2692   if( curtune->at_curpanel != PN_TRACKER ) return;
2693 
2694   if( !force )
2695   {
2696     if( ( tmr_lasttune == curtune ) &&
2697         ( tmr_lasttime == ((curtune->at_hours<<16)|(curtune->at_mins<<8)|curtune->at_secs) ) )
2698       return;
2699   }
2700 
2701   tmr_lasttune = curtune;
2702   tmr_lasttime = (curtune->at_hours<<16)|(curtune->at_mins<<8)|curtune->at_secs;
2703 
2704   sprintf( tbuf, "%02d:%02d:%02d", curtune->at_hours, curtune->at_mins, curtune->at_secs );
2705 
2706   set_font(&mainbm, FONT_FIX, FALSE);
2707   set_fpen(&mainbm, PAL_BACK);
2708   fillrect_xy(&mainbm, 546, 132, 546+65, 132+15 );
2709   set_fpen(&mainbm, PAL_TEXT);
2710   printstr(&mainbm, tbuf, 546, 132);
2711 }
2712 
gui_render_tunepanel(BOOL force)2713 void gui_render_tunepanel( BOOL force )
2714 {
2715   int32 panel, i;
2716 
2717   if( curtune == NULL )
2718     panel = PN_TRACKER;
2719   else
2720     panel = curtune->at_curpanel;
2721 
2722   switch( panel )
2723   {
2724     case PN_TRACKER:
2725       if( force )
2726       {
2727         put_bitmap( BM_BG_TRACKER, 0, 120, 800, 480 );
2728         gui_render_track_buttonbank();
2729         gui_render_tabs();
2730         for( i=0; i<NB_END; i++ )
2731           gui_render_nbox( curtune, PN_TRACKER, &trk_nb[i] );
2732       }
2733       gui_render_timer( force );
2734       gui_render_tracker( force );
2735       break;
2736 
2737     case PN_INSED:
2738       if( force )
2739       {
2740         put_bitmap( BM_BG_INSED, 0, 120, 800, 480 );
2741         gui_render_tabs();
2742         gui_render_perf( curtune, curtune ? &curtune->at_Instruments[curtune->at_curins] : NULL, force );
2743         for( i=0; i<INB_END; i++ )
2744           gui_render_nbox( curtune, PN_INSED, &ins_nb[i] );
2745         for( i=0; i<TB_END; i++ )
2746           gui_render_tbox( &mainbm, &tbx[i] );
2747         gui_render_inslistb( force );
2748       }
2749       break;
2750   }
2751 
2752 }
2753 
gui_set_rempos(struct ahx_tune * at)2754 void gui_set_rempos( struct ahx_tune *at )
2755 {
2756   at->at_rempos[0] = 0;
2757   at->at_rempos[1] = at->at_TrackLength>>2;
2758   at->at_rempos[2] = at->at_TrackLength>>1;
2759   at->at_rempos[3] = (at->at_TrackLength*3)/4;
2760   at->at_rempos[4] = at->at_TrackLength-1;
2761 }
2762 
gui_update_from_nbox(int32 panel,struct numberbox * bp,int32 i)2763 void gui_update_from_nbox( int32 panel, struct numberbox *bp, int32 i )
2764 {
2765   struct ahx_tune *at;
2766   struct ahx_instrument *ip;
2767   int32 j;
2768 
2769   if( bp[i].cnum < bp[i].min ) bp[i].cnum = bp[i].min;
2770   if( bp[i].cnum > bp[i].max ) bp[i].cnum = bp[i].max;
2771 
2772   at = curtune;
2773   if( at == NULL ) return;
2774 
2775   switch( at->at_curpanel )
2776   {
2777     case PN_TRACKER:
2778       switch( i )
2779       {
2780         case NB_POSNR:
2781           if( at->at_doing == D_PLAYING )
2782             at->at_NextPosNr = bp[i].cnum;
2783           else
2784             at->at_PosNr = bp[i].cnum;
2785           gui_render_tracker( FALSE );
2786           return;
2787         case NB_LENGTH:
2788           modify_tune_w( at, UNT_POSITIONNR, bp[i].cnum );
2789           break;
2790         case NB_RESPOS:
2791           modify_tune_w( at, UNT_RESTART, bp[i].cnum );
2792           break;
2793         case NB_TRKLEN:
2794           j = bp[NB_TRKLEN].cnum;
2795           if( j < 1 ) j = 1;
2796           modify_tune_b( at, UNT_TRACKLEN, j );
2797           if( at->at_NoteNr >= at->at_TrackLength )
2798             at->at_NoteNr = at->at_TrackLength-1;
2799           gui_set_rempos( curtune );
2800           trked_lastposnr = 8000;
2801           gui_render_tracker( FALSE );
2802           break;
2803         case NB_SSNR:
2804           modify_tune_w( at, UNT_SUBSONGS, bp[NB_SSNR].cnum );
2805           gui_set_various_things( at );
2806           break;
2807         case NB_CURSS:
2808           at->at_curss = bp[NB_CURSS].cnum;
2809           rp_init_subsong( at, bp[NB_CURSS].cnum );
2810           gui_set_various_things( at );
2811           gui_render_tracker( FALSE );
2812           break;
2813         case NB_SSPOS:
2814           if( at->at_curss > 0 )
2815             modify_sspos( at, bp[NB_SSPOS].cnum );
2816           break;
2817         case NB_CHANS:
2818           rp_stop();
2819           gui_render_tracked( TRUE );  // Kill the VUMeters
2820           gui_render_wavemeter();
2821           at->at_doing = D_IDLE;
2822           j = bp[NB_CHANS].cnum;
2823           if( j < 4 ) j = 4;
2824           if( j > MAX_CHANNELS ) j = MAX_CHANNELS;
2825           modify_tune_b( at, UNT_CHANNELS, j );
2826           at->at_curlch = 0;
2827           at->at_tracked_curs = 0;
2828           at->at_posed_curs = 0;
2829           gui_render_tracker( TRUE );
2830           break;
2831 
2832         case NB_MIXG:
2833           j = bp[NB_MIXG].cnum;
2834           if( j < 0 ) j = 0;
2835           if( j > 200 ) j = 200;
2836           modify_tune_b( at, UNT_MIXGAIN, j );
2837           at->at_mixgain = (j*256)/100;
2838           break;
2839 
2840         case NB_SPEEDMULT:
2841           j = bp[NB_SPEEDMULT].cnum;
2842           if( j < 1 ) j = 1;
2843           if( j > 4 ) j = 4;
2844           modify_tune_b( at, UNT_SPMUL, j );
2845           break;
2846 
2847         case NB_DRUMPADMODE:
2848           j = bp[NB_DRUMPADMODE].cnum;
2849           if( j < 0 ) j = 0;
2850           if( j > 1 ) j = 1;
2851           at->at_drumpadmode = j;
2852           break;
2853       }
2854 
2855       gui_render_nbox( at, PN_TRACKER, &bp[i] );
2856       break;
2857 
2858     case PN_INSED:
2859       ip = &at->at_Instruments[at->at_curins];
2860       switch( i )
2861       {
2862         case INB_INS:
2863           at->at_curins = bp[i].cnum;
2864           gui_render_nbox( at, PN_INSED, &bp[i] );
2865           gui_set_various_things( at );
2866           return;
2867         case INB_VOL:
2868           if( ip == NULL ) break;
2869           modify_ins_b( at, ip, UNT_INS_VOLUME, bp[i].cnum );
2870           break;
2871         case INB_WAVELEN:
2872           if( ip == NULL ) break;
2873           modify_ins_b( at, ip, UNT_INS_WAVELENGTH, bp[i].cnum );
2874 
2875           switch( ip->ins_WaveLength )
2876           {
2877             case 0:
2878               j = 0x20;
2879               break;
2880             case 1:
2881               j = 0x10;
2882               break;
2883             case 2:
2884               j = 0x08;
2885               break;
2886             case 3:
2887               j = 0x04;
2888               break;
2889             case 4:
2890               j = 0x02;
2891               break;
2892             default:
2893               j = 0x01;
2894               break;
2895           }
2896 
2897           ins_nb[INB_SQRLOWER].min = j;
2898           ins_nb[INB_SQRUPPER].min = j;
2899 
2900           if( ip->ins_SquareLowerLimit < j )
2901             ip->ins_SquareLowerLimit = j;
2902           if( ip->ins_SquareUpperLimit < j )
2903             ip->ins_SquareUpperLimit = j;
2904 
2905           ins_nb[INB_SQRLOWER].cnum = ip->ins_SquareLowerLimit;
2906           ins_nb[INB_SQRUPPER].cnum = ip->ins_SquareUpperLimit;
2907 
2908           gui_render_nbox( at, PN_INSED, &bp[INB_SQRLOWER] );
2909           gui_render_nbox( at, PN_INSED, &bp[INB_SQRUPPER] );
2910           break;
2911         case INB_ATTACK:
2912           if( ip == NULL ) break;
2913           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_AFRAMES, bp[i].cnum );
2914           break;
2915         case INB_AVOL:
2916           if( ip == NULL ) break;
2917           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_AVOLUME, bp[i].cnum );
2918           break;
2919         case INB_DECAY:
2920           if( ip == NULL ) break;
2921           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_DFRAMES, bp[i].cnum );
2922           break;
2923         case INB_DVOL:
2924           if( ip == NULL ) break;
2925           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_DVOLUME, bp[i].cnum );
2926           break;
2927         case INB_SUSTAIN:
2928           if( ip == NULL ) break;
2929           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_SFRAMES, bp[i].cnum );
2930           break;
2931         case INB_RELEASE:
2932           if( ip == NULL ) break;
2933           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_RFRAMES, bp[i].cnum );
2934           break;
2935         case INB_RVOL:
2936           if( ip == NULL ) break;
2937           modify_env_w( at, &ip->ins_Envelope, UNT_ENV_RVOLUME, bp[i].cnum );
2938           break;
2939         case INB_VIBDELAY:
2940           if( ip == NULL ) break;
2941           modify_ins_b( at, ip, UNT_INS_VIBRATODELAY, bp[i].cnum );
2942           break;
2943         case INB_VIBDEPTH:
2944           if( ip == NULL ) break;
2945           modify_ins_b( at, ip, UNT_INS_VIBRATODEPTH, bp[i].cnum );
2946           break;
2947         case INB_VIBSPEED:
2948           if( ip == NULL ) break;
2949           modify_ins_b( at, ip, UNT_INS_VIBRATOSPEED, bp[i].cnum );
2950           break;
2951         case INB_SQRLOWER:
2952           if( ip == NULL ) break;
2953           modify_ins_b( at, ip, UNT_INS_SQUARELOWERLIMIT, bp[i].cnum );
2954           break;
2955         case INB_SQRUPPER:
2956           if( ip == NULL ) break;
2957           modify_ins_b( at, ip, UNT_INS_SQUAREUPPERLIMIT, bp[i].cnum );
2958           break;
2959         case INB_SQRSPEED:
2960           if( ip == NULL ) break;
2961           modify_ins_b( at, ip, UNT_INS_SQUARESPEED, bp[i].cnum );
2962           break;
2963         case INB_FLTLOWER:
2964           if( ip == NULL ) break;
2965           modify_ins_b( at, ip, UNT_INS_FILTERLOWERLIMIT, bp[i].cnum );
2966           break;
2967         case INB_FLTUPPER:
2968           if( ip == NULL ) break;
2969           modify_ins_b( at, ip, UNT_INS_FILTERUPPERLIMIT, bp[i].cnum );
2970           break;
2971         case INB_FLTSPEED:
2972           if( ip == NULL ) break;
2973           modify_ins_b( at, ip, UNT_INS_FILTERSPEED, bp[i].cnum );
2974           break;
2975         case INB_PERFSPEED:
2976           if( ip == NULL ) break;
2977           modify_pls_w( at, &ip->ins_PList, UNT_PLS_SPEED, bp[i].cnum );
2978           break;
2979         case INB_PERFLEN:
2980           if( ip == NULL ) break;
2981           modify_pls_w( at, &ip->ins_PList, UNT_PLS_LENGTH, bp[i].cnum );
2982           gui_render_perf( curtune, ip, FALSE );
2983           break;
2984         case INB_HARDCUT:
2985           if( ip == NULL ) break;
2986           modify_ins_b( at, ip, UNT_INS_HARDCUTRELEASEFRAMES, bp[i].cnum );
2987           break;
2988         case INB_RELCUT:
2989           if( ip == NULL ) break;
2990           modify_ins_b( at, ip, UNT_INS_HARDCUTRELEASE, bp[i].cnum );
2991           break;
2992       }
2993 
2994       gui_render_nbox( at, PN_INSED, &bp[i] );
2995       break;
2996   }
2997 }
2998 
gui_set_popup(int32 pn,int16 x,int16 y)2999 void gui_set_popup( int32 pn, int16 x, int16 y )
3000 {
3001   pp[pn].x = x;
3002   pp[pn].y = y;
3003 }
3004 
gui_render_popup(int32 pn,BOOL pressed)3005 void gui_render_popup( int32 pn, BOOL pressed )
3006 {
3007   if( pressed )
3008     put_ppartbitmap( BM_DIRPOPUP, 0, 18, pp[pn].x, pp[pn].y, 20, 18 );
3009   else
3010     put_pbitmap( BM_DIRPOPUP, pp[pn].x, pp[pn].y, 20, 18 );
3011 }
3012 
gui_set_pcycle(int32 cn,int16 x,int16 y,int32 cur,TEXT ** opts)3013 void gui_set_pcycle( int32 cn, int16 x, int16 y, int32 cur, TEXT **opts )
3014 {
3015   int32 i;
3016 
3017   for( i=0; opts[i] != NULL; i++ ) ;
3018 
3019   if( cur >= i ) cur = 0;
3020 
3021   pcyc[cn].x = x;
3022   pcyc[cn].y = y;
3023   pcyc[cn].numopts = i;
3024   pcyc[cn].copt = cur;
3025   pcyc[cn].options = opts;
3026   pcyc[cn].zone = gui_add_zone( &pzones[0], &numpzones, MAX_PZONES, x, y, 160, 24 );
3027 }
3028 
gui_render_pcycle(int32 cn,BOOL pressed)3029 void gui_render_pcycle( int32 cn, BOOL pressed )
3030 {
3031   int w, tx;
3032   const TEXT *ctxt;
3033 
3034   if( pressed )
3035     put_ppartbitmap( BM_PRF_CYCLE, 0, 24, pcyc[cn].x, pcyc[cn].y, 158, 24 );
3036   else
3037     put_pbitmap( BM_PRF_CYCLE, pcyc[cn].x, pcyc[cn].y, 158, 24 );
3038 
3039 
3040   ctxt = pcyc[cn].options[pcyc[cn].copt];
3041   if( ctxt == NULL ) return;
3042 
3043   set_font(&prefbm, FONT_PRP, FALSE);
3044 
3045 #ifndef __SDL_WRAPPER__
3046   w = IGraphics->TextLength( &prefbm.rp, ctxt, strlen( ctxt ) );
3047 #else
3048   TTF_SizeText(prefbm.font, ctxt, &w, &tx);
3049 #endif
3050   tx = pcyc[cn].x+pw_bl+(79-(w>>1));
3051 
3052   set_fpen(&prefbm, PAL_BTNSHADOW);
3053   printstr(&prefbm, ctxt, tx+1, pcyc[cn].y+pw_bt+5);
3054   set_fpen(&prefbm, PAL_BTNTEXT);
3055   printstr(&prefbm, ctxt, tx, pcyc[cn].y+pw_bt+4);
3056 
3057 #if defined(WIN32) || defined(__APPLE__)
3058   if (cn == 0)
3059   {
3060     set_fpen(&prefbm, PAL_BACK);
3061     for (w=0; w<24; w+=3)
3062       fillrect_xy(&prefbm, pcyc[0].x, pcyc[0].y+w, pcyc[0].x+157, pcyc[0].y+w);
3063   }
3064 #endif
3065 }
3066 
gui_render_prefs(void)3067 void gui_render_prefs( void )
3068 {
3069   int32 i;
3070 
3071   bm_to_bm( &bitmaps[BM_PRF_BG], 0, 0, &prefbm, pw_bl, pw_bt, 400, 300);
3072 
3073   for( i=0; i<PC_END; i++ )
3074     gui_render_pcycle( i, FALSE );
3075 
3076   for( i=0; i<PTB_END; i++ )
3077     gui_render_tbox( &prefbm, &ptb[i] );
3078 
3079   for( i=0; i<PP_END; i++ )
3080     gui_render_popup( i, FALSE );
3081 
3082 #ifdef __SDL_WRAPPER__
3083   set_fpen(&prefbm, PAL_BTNSHADOW);
3084   printstr(&prefbm, "ESC to close", 5, 281);
3085   set_fpen(&prefbm, PAL_BTNTEXT);
3086   printstr(&prefbm, "ESC to close", 4, 280);
3087   bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
3088 #endif
3089 }
3090 
gui_open_prefs(void)3091 void gui_open_prefs( void )
3092 {
3093   pref_dorestart = FALSE;
3094   pref_oldfullscr = pref_fullscr;
3095   strcpy( pref_oldskindir, skindir );
3096 
3097 #ifndef __SDL_WRAPPER__
3098   if( pw_x == -1 ) pw_x = mainwin->LeftEdge + 150;
3099   if( pw_y == -1 ) pw_y = mainwin->TopEdge + 100;
3100 
3101   prefwin = IIntuition->OpenWindowTags( NULL,
3102     WA_Left,        pw_x,
3103     WA_Top,         pw_y,
3104     WA_InnerWidth,  400,
3105     WA_InnerHeight, 300,
3106     WA_Title,       "Preferences",
3107     WA_ScreenTitle, "HivelyTracker (c)2013 IRIS & Up Rough! - http://www.uprough.net - http://www.hivelytracker.co.uk",
3108     WA_RMBTrap,     TRUE,
3109     WA_IDCMP,       IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_GADGETUP|IDCMP_EXTENDEDMOUSE,
3110     WA_Activate,    TRUE,
3111     WA_DragBar,     TRUE,
3112     WA_CloseGadget, TRUE,
3113     WA_DepthGadget, TRUE,
3114     fullscr ? WA_CustomScreen : TAG_IGNORE, scr,
3115     TAG_DONE );
3116   if( !prefwin )
3117   {
3118     printf( "Unable to open prefs window!\n" );
3119     prefwin_sig = 0;
3120     return;
3121   }
3122 
3123   memset(&prefbm, 0, sizeof(struct rawbm));
3124   memcpy(&prefbm.rp, prefwin->RPort, sizeof(struct RastPort));
3125   prefbm.bm = prefwin->RPort->BitMap;
3126 
3127   pw_bl = prefwin->BorderLeft;
3128   pw_bt = prefwin->BorderTop;
3129 
3130 #else
3131   pw_bl = 0;
3132   pw_bt = 0;
3133 #endif
3134 
3135   set_font(&prefbm, FONT_PRP, FALSE);
3136 
3137   gui_set_pcycle( PC_WMODE,     220, 8     , pref_fullscr ? 1 : 0, pc_wmode_opts );
3138   gui_set_pcycle( PC_DEFSTEREO, 220, 8+24*1, pref_defstereo,  pc_defst_opts );
3139   gui_set_pcycle( PC_BLANKZERO, 220, 8+24*2, pref_blankzeros, pc_bzero_opts );
3140 
3141   gui_set_tbox( &ptb[PTB_SONGDIR], 220+pw_bl, 8+24*3+4+pw_bt, 136, songdir, 511, TBF_ENABLED|TBF_VISIBLE, 0 );
3142   gui_set_tbox( &ptb[PTB_INSTDIR], 220+pw_bl, 8+24*4+4+pw_bt, 136, instdir, 511, TBF_ENABLED|TBF_VISIBLE, 0 );
3143   gui_set_tbox( &ptb[PTB_SKINDIR], 220+pw_bl, 8+24*5+4+pw_bt, 136, skindir, 511, TBF_ENABLED|TBF_VISIBLE, 0 );
3144 
3145   gui_set_popup( PP_SONGDIR, 360, 8+24*3+3 );
3146   gui_set_popup( PP_INSTDIR, 360, 8+24*4+3 );
3147   gui_set_popup( PP_SKINDIR, 360, 8+24*5+3 );
3148 
3149 
3150   gui_set_pcycle( PC_MAXUNDOBUF, 220, 8+24*6, pref_maxundobuf, pc_mundo_opts );
3151 
3152   gui_render_prefs();
3153 
3154 #ifndef __SDL_WRAPPER__
3155   prefwin_sig = (1L<<prefwin->UserPort->mp_SigBit);
3156   gui_sigs |= prefwin_sig;
3157 #else
3158   prefwin_open = TRUE;
3159 #endif
3160 }
3161 
gui_close_prefs(void)3162 void gui_close_prefs( void )
3163 {
3164   int32 i;
3165 
3166   for( i=0; i<MAX_PZONES; i++ )
3167     pzones[i].x = -1;
3168   numpzones = 0;
3169 
3170 #ifndef __SDL_WRAPPER__
3171   if( prefwin )
3172   {
3173     pw_x = prefwin->LeftEdge;
3174     pw_y = prefwin->TopEdge;
3175     IIntuition->CloseWindow( prefwin );
3176   }
3177 
3178   prefwin = NULL;
3179   gui_sigs &= ~prefwin_sig;
3180   prefwin_sig = 0;
3181   memset(&prefbm.rp, 0, sizeof(struct RastPort));
3182   prefbm.bm = NULL;
3183 
3184   for( i=0; i<PTB_END; i++ )
3185   {
3186     if( ptb[i].bm.bm ) IGraphics->FreeBitMap( ptb[i].bm.bm );
3187     ptb[i].bm.bm = NULL;
3188   }
3189 #else
3190   prefwin_open = FALSE;
3191   aboutwin_open = FALSE;
3192 
3193   for( i=0; i<PTB_END; i++ )
3194   {
3195     if( ptb[i].bm.srf ) SDL_FreeSurface( ptb[i].bm.srf );
3196     ptb[i].bm.srf = NULL;
3197   }
3198 
3199   gui_render_everything();
3200 #endif
3201 
3202   if( ( pref_oldfullscr != pref_fullscr ) ||
3203       ( strcmp( pref_oldskindir, skindir ) != 0 ) )
3204     pref_dorestart = TRUE;
3205 }
3206 
gui_encode_pstr(TEXT * out,const TEXT * in)3207 TEXT *gui_encode_pstr( TEXT *out, const TEXT *in )
3208 {
3209   int32 ic, oc;
3210 
3211   ic=oc=0;
3212   while( in[ic] )
3213   {
3214     if(( in[ic] == 39 ) || ( in[ic] == '\\' )) out[oc++] = '\\';
3215     out[oc++] = in[ic++];
3216   }
3217 
3218   out[oc] = 0;
3219   return out;
3220 }
3221 
gui_decode_pstr(const TEXT * tag,TEXT * buf)3222 BOOL gui_decode_pstr( const TEXT *tag, TEXT *buf )
3223 {
3224   int32 ic, oc;
3225 
3226   ic=oc=0;
3227 
3228   if( strncmp( buf, tag, strlen( tag ) ) != 0 )
3229     return FALSE;
3230 
3231   ic = strlen( tag );
3232 
3233   // Skip whitespace
3234   while( isws( buf[ic] ) ) ic++;
3235 
3236   // equals?
3237   if( buf[ic] != '=' ) return FALSE;
3238 
3239   ic++;
3240   while( isws( buf[ic] ) ) ic++;
3241 
3242   // Starts with a quote?
3243   if( buf[ic] != 39 ) return FALSE;
3244 
3245   ic++;
3246   while( buf[ic] )
3247   {
3248     // Escaped char?
3249     if( ( buf[ic] == '\\' ) && ( buf[ic+1] != 0 ) )
3250     {
3251       buf[oc++] = buf[ic+1];
3252       ic += 2;
3253       continue;
3254     }
3255 
3256     // Terminating quote?
3257     if( buf[ic] == 39 )
3258     {
3259       buf[oc] = 0;
3260       return TRUE;
3261     }
3262 
3263     // Carry on
3264     buf[oc++] = buf[ic++];
3265   }
3266 
3267   // Missing quote
3268   buf[oc] = 0;
3269   return FALSE;
3270 }
3271 
gui_decode_num(const TEXT * tag,const TEXT * buf,int32 * val)3272 BOOL gui_decode_num( const TEXT *tag, const TEXT *buf, int32 *val )
3273 {
3274   uint32 ic;
3275 
3276   *val = 0;
3277 
3278   if( strncmp( buf, tag, strlen( tag ) ) != 0 )
3279     return FALSE;
3280 
3281   ic = strlen( tag );
3282   while( isws( buf[ic] ) ) ic++;
3283 
3284   if( buf[ic] != '=' ) return FALSE;
3285   ic++;
3286 
3287   while( isws( buf[ic] ) ) ic++;
3288 
3289   *val = atoi( &buf[ic] );
3290   return TRUE;
3291 }
3292 
gui_loadskinsettings(void)3293 void gui_loadskinsettings( void )
3294 {
3295   FILE *f;
3296   TEXT tmp[1024];
3297   int32 pen, col, i;
3298 
3299   tabtextback = FALSE;
3300   tabtextshad = TRUE;
3301 
3302 #ifdef __APPLE__
3303   if (strncmp(skindir, "Skins/", 6) == 0)
3304     osxGetResourcesPath(tmp, skindir);
3305 #else
3306   strncpy( tmp, skindir, 1024 );
3307 #endif
3308 
3309 #ifndef __SDL_WRAPPER__
3310   IDOS->AddPart( tmp, "Settings_os4", 1024 );
3311 #else
3312   strncat( tmp, "/Settings_os4", 1024 );
3313 #endif
3314 
3315   f = fopen( tmp, "r" );
3316   if( !f ) return;
3317 
3318   pen = 0;
3319   while( fgets(tmp, 1024, f) )
3320   {
3321     if( gui_decode_pstr( "skinext", tmp ) )
3322     {
3323       strncpy( skinext, tmp, 32 );
3324       continue;
3325     }
3326 
3327     if( gui_decode_pstr( "font1", tmp ) )
3328     {
3329 //      strcpy( prpfontname, tmp );
3330       continue;
3331     }
3332 
3333     if( gui_decode_pstr( "font2", tmp ) )
3334     {
3335 //      strcpy( fixfontname, tmp );
3336       continue;
3337     }
3338 
3339     if( gui_decode_pstr( "font3", tmp ) )
3340     {
3341 //      strcpy( sfxfontname, tmp );
3342       continue;
3343     }
3344 
3345     if( gui_decode_pstr( "tabtextback", tmp ) )
3346     {
3347       if( strcasecmp( tmp, "Yes" ) == 0 )
3348         tabtextback = TRUE;
3349       else
3350         tabtextback = FALSE;
3351       continue;
3352     }
3353 
3354     if( gui_decode_pstr( "tabtextshad", tmp ) )
3355     {
3356       if( strcasecmp( tmp, "Yes" ) == 0 )
3357         tabtextshad = TRUE;
3358       else
3359         tabtextshad = FALSE;
3360       continue;
3361     }
3362 
3363     col = 0;
3364     if( ishex( tmp[0] ) )
3365     {
3366       // No more pens
3367       if( pen >= PAL_END ) continue;
3368 
3369       i=0;
3370       while( ishex( tmp[i] ) )
3371       {
3372         col <<= 4;
3373         if(( tmp[i] >= '0' ) && ( tmp[i] <= '9' )) col += tmp[i]-'0';
3374         if(( tmp[i] >= 'A' ) && ( tmp[i] <= 'F' )) col += tmp[i]-('A'-10);
3375         if(( tmp[i] >= 'a' ) && ( tmp[i] <= 'f' )) col += tmp[i]-('a'-10);
3376         i++;
3377       }
3378 
3379       pal[pen] = col;
3380 #ifdef __SDL_WRAPPER__
3381 #ifdef __APPLE__
3382       // Work-around for SDL bug on OSX
3383       mappal[pen] = SDL_MapRGB(ssrf->format, col&0xff, (col>>8)&0xff, (col>>16)&0xff) >> 8;
3384 #else
3385       mappal[pen] = SDL_MapRGB(ssrf->format, (col>>16)&0xff, (col>>8)&0xff, col&0xff);
3386 #endif
3387 #endif
3388       // Just in case the skin doesn't specify
3389       // tab colours
3390       if( pen == PAL_BTNTEXT )   pal[PAL_TABTEXT]   = col;
3391       if( pen == PAL_BTNSHADOW ) pal[PAL_TABSHADOW] = col;
3392 
3393       pen++;
3394     }
3395   }
3396 
3397   fclose(f);
3398 }
3399 
gui_load_prefs(void)3400 void gui_load_prefs( void )
3401 {
3402   FILE *f;
3403   int32 i;
3404   TEXT tmp[256];
3405 
3406 #ifdef __APPLE__
3407   f = fopen( osxGetPrefsPath(), "r");
3408 #else
3409   f = fopen( "ht.prefs", "r" );
3410 #endif
3411   if( !f ) return;
3412 
3413   while( fgets(tmp, 256, f) )
3414   {
3415 #ifdef __SDL_WRAPPER__
3416     if( gui_decode_num( "rctrlplaypos", tmp, &i ) )
3417     {
3418 #ifdef __WIN32__ /* On Win32 RALT generates phantom RCTRL presses that stop this being workable */
3419       pref_rctrlplaypos = FALSE;
3420 #else
3421       pref_rctrlplaypos = (i!=0);
3422 #endif
3423       continue;
3424     }
3425 #endif
3426 
3427     if( gui_decode_num( "display", tmp, &i ) )
3428     {
3429       pref_fullscr = (i!=0);
3430       continue;
3431     }
3432 
3433     if( gui_decode_num( "defstereo", tmp, &i ) )
3434     {
3435       if( i < 0 ) i = 0;
3436       if( i > 4 ) i = 4;
3437       pref_defstereo = i;
3438       continue;
3439     }
3440 
3441     if( gui_decode_num( "blankzero", tmp, &i ) )
3442     {
3443       pref_blankzeros = (i!=0);
3444       continue;
3445     }
3446 
3447     if( gui_decode_num( "maxundobf", tmp, &i ) )
3448     {
3449       if( i < 0 ) i = 0;
3450       if( i > 5 ) i = 5;
3451       pref_maxundobuf = i;
3452       continue;
3453     }
3454 
3455     if( gui_decode_pstr( "songdir", tmp ) )
3456     {
3457       strcpy( songdir, tmp );
3458       continue;
3459     }
3460 
3461     if( gui_decode_pstr( "instdir", tmp ) )
3462     {
3463       strcpy( instdir, tmp );
3464       continue;
3465     }
3466 
3467     if( gui_decode_pstr( "skindir", tmp ) )
3468     {
3469       strcpy( skindir, tmp );
3470       continue;
3471     }
3472 
3473     if( gui_decode_num( "posedadvance", tmp, &i ) )
3474     {
3475       posedadvance = (i!=0);
3476       continue;
3477     }
3478 
3479     if( gui_decode_num( "notejump", tmp, &i ) )
3480     {
3481       if( i < 0 ) i = 0;
3482       if( i > 9 ) i = 9;
3483       defnotejump = i;
3484       continue;
3485     }
3486 
3487     if( gui_decode_num( "inotejump", tmp, &i ) )
3488     {
3489       if( i < 0 ) i = 0;
3490       if( i > 9 ) i = 9;
3491       definotejump = i;
3492       continue;
3493     }
3494   }
3495 
3496   fclose(f);
3497 
3498 #if defined(WIN32) || defined(APPLE)
3499   pref_fullscr = FALSE;
3500 #endif
3501 }
3502 
gui_pre_init(void)3503 void gui_pre_init( void )
3504 {
3505   uint32 i;
3506 
3507 #ifndef __SDL_WRAPPER__
3508   for( i=0; i<BM_END; i++ ) bitmaps[i].bm = NULL;
3509   for( i=0; i<TB_END; i++ ) tbx[i].bm.bm = NULL;
3510 #else
3511   for( i=0; i<BM_END; i++ ) bitmaps[i].srf = NULL;
3512   for( i=0; i<TB_END; i++ ) tbx[i].bm.srf = NULL;
3513 #endif
3514 
3515   strcpy( songdir, "Songs" );
3516   strcpy( instdir, "Instruments" );
3517   strcpy( skindir, "Skins/SIDMonster-Light" );
3518 
3519   gui_load_prefs();
3520 
3521   // Remove me later ...
3522   if ( songdir[0] == 0 ) strcpy(songdir, "Songs");
3523   if ( instdir[0] == 0 ) strcpy(instdir, "Instruments");
3524 
3525 #ifdef __SDL_WRAPPER__
3526   strncpy( remsongdir, songdir, 512 );
3527   strncpy( reminstdir, instdir, 512 );
3528 #endif
3529 
3530   memset(&prefbm, 0, sizeof(prefbm));
3531 }
3532 
gui_save_prefs(void)3533 void gui_save_prefs( void )
3534 {
3535   FILE *f;
3536   TEXT tmp[1024];
3537 
3538 #ifdef __APPLE__
3539   f = fopen( osxGetPrefsPath(), "w" );
3540 #else
3541   f = fopen( "ht.prefs", "w" );
3542 #endif
3543   if( !f ) return;
3544 
3545   fprintf( f, "display = %d\n",   (int)pref_fullscr );
3546   fprintf( f, "defstereo = %d\n", (int)pref_defstereo );
3547   fprintf( f, "blankzero = %d\n", (int)pref_blankzeros );
3548   fprintf( f, "maxundobf = %d\n", (int)pref_maxundobuf );
3549   fprintf( f, "songdir = '%s'\n",  gui_encode_pstr( tmp, songdir ) );
3550   fprintf( f, "instdir = '%s'\n",  gui_encode_pstr( tmp, instdir ) );
3551   fprintf( f, "skindir = '%s'\n",  gui_encode_pstr( tmp, skindir ) );
3552   fprintf( f, "posedadvance = %d\n", (int)posedadvance );
3553   fprintf( f, "notejump = %d\n",  (int)defnotejump );
3554   fprintf( f, "inotejump = %d\n",  (int)definotejump );
3555 #ifdef __SDL_WRAPPER__
3556   fprintf( f, "rctrlplaypos = %d\n", (int)pref_rctrlplaypos);
3557 #endif
3558   fclose( f );
3559 }
3560 
gui_open_skin_images(void)3561 BOOL gui_open_skin_images( void )
3562 {
3563   gui_loadskinsettings();
3564 
3565   if( !open_image( "logo",        &bitmaps[BM_LOGO] ) ) return FALSE;
3566   if( !open_image( "tab_area",    &bitmaps[BM_TAB_AREA] ) )    return FALSE;
3567   if( !open_image( "tab_left",    &bitmaps[BM_TAB_LEFT] ) )    return FALSE;
3568   if( !open_image( "tab_mid",     &bitmaps[BM_TAB_MID] ) )     return FALSE;
3569   if( !open_image( "tab_right",   &bitmaps[BM_TAB_RIGHT] ) )   return FALSE;
3570   if( !open_image( "itab_left",   &bitmaps[BM_ITAB_LEFT] ) )   return FALSE;
3571   if( !open_image( "itab_mid",    &bitmaps[BM_ITAB_MID] ) )    return FALSE;
3572   if( !open_image( "itab_right",  &bitmaps[BM_ITAB_RIGHT] ) )  return FALSE;
3573 
3574   if( tabtextback )
3575   {
3576     if( !open_image( "itab_text",   &bitmaps[BM_ITAB_TEXT] ) )   return FALSE;
3577     if( !open_image( "tab_text",    &bitmaps[BM_TAB_TEXT] ) )    return FALSE;
3578   }
3579 
3580   if( !open_image( "butbankr",    &bitmaps[BM_BUTBANKR] ) )    return FALSE;
3581   if( !open_image( "butbankp",    &bitmaps[BM_BUTBANKP] ) )    return FALSE;
3582   if( !open_image( "bg_tracker",  &bitmaps[BM_BG_TRACKER] ) )  return FALSE;
3583   if( !open_image( "bg_insed",    &bitmaps[BM_BG_INSED] ) )    return FALSE;
3584   if( !open_image( "plusminus",   &bitmaps[BM_PLUSMINUS] ) )   return FALSE;
3585   if( !open_image( "vumeter",     &bitmaps[BM_VUMETER] ) )     return FALSE;
3586   if( !open_image( "depth",       &bitmaps[BM_DEPTH] ) )       return FALSE;
3587   if( !open_image( "blank",       &bitmaps[BM_BLANK] ) )       return FALSE;
3588   if( !open_image( "wavemeter",   &bitmaps[BM_WAVEMETERS] ) )  return FALSE;
3589   if( !open_image( "prefs_os4",   &bitmaps[BM_PRF_BG] ) )      return FALSE;
3590   if( !open_image( "prefs_cycle", &bitmaps[BM_PRF_CYCLE] ) )   return FALSE;
3591   if( !open_image( "trkbankr",    &bitmaps[BM_TRKBANKR] ) )    return FALSE;
3592   if( !open_image( "trkbankp",    &bitmaps[BM_TRKBANKP] ) )    return FALSE;
3593   if( !open_image( "chanmute",    &bitmaps[BM_CHANMUTE] ) )    return FALSE;
3594   if( !open_image( "dir_popup",   &bitmaps[BM_DIRPOPUP] ) )    return FALSE;
3595 
3596   return TRUE;
3597 }
3598 
gui_open(void)3599 BOOL gui_open( void )
3600 {
3601   int32 i;
3602 
3603   fullscr = pref_fullscr;
3604 
3605 #ifndef __SDL_WRAPPER__
3606   // Make our drag gadget
3607   gad_drag.NextGadget    = &gad_drag2;
3608   gad_drag.LeftEdge      = 24;
3609   gad_drag.TopEdge       = 0;
3610   gad_drag.Width         = 232;
3611   gad_drag.Height        = 24;
3612   gad_drag.Flags         = GFLG_GADGHNONE;
3613   gad_drag.Activation    = 0;
3614   gad_drag.GadgetType    = GTYP_WDRAGGING;
3615   gad_drag.GadgetRender  = NULL;
3616   gad_drag.SelectRender  = NULL;
3617   gad_drag.GadgetText    = NULL;
3618   gad_drag.MutualExclude = 0;
3619   gad_drag.SpecialInfo   = NULL;
3620   gad_drag.GadgetID      = 0;
3621   gad_drag.UserData      = NULL;
3622 
3623   gad_drag2.NextGadget    = &gad_depth;
3624   gad_drag2.LeftEdge      = 0;
3625   gad_drag2.TopEdge       = 24;
3626   gad_drag2.Width         = 256;
3627   gad_drag2.Height        = 72;
3628   gad_drag2.Flags         = GFLG_GADGHNONE;
3629   gad_drag2.Activation    = 0;
3630   gad_drag2.GadgetType    = GTYP_WDRAGGING;
3631   gad_drag2.GadgetRender  = NULL;
3632   gad_drag2.SelectRender  = NULL;
3633   gad_drag2.GadgetText    = NULL;
3634   gad_drag2.MutualExclude = 0;
3635   gad_drag2.SpecialInfo   = NULL;
3636   gad_drag2.GadgetID      = 0;
3637   gad_drag2.UserData      = NULL;
3638 
3639   // Make our depth gadget
3640   gad_depth.NextGadget    = NULL;
3641   gad_depth.LeftEdge      = 776;
3642   gad_depth.TopEdge       = 0;
3643   gad_depth.Width         = 24;
3644   gad_depth.Height        = 24;
3645   gad_depth.Flags         = 0;
3646   gad_depth.Activation    = 0;
3647   gad_depth.GadgetType    = GTYP_WDEPTH;
3648   gad_depth.GadgetRender  = NULL;
3649   gad_depth.SelectRender  = NULL;
3650   gad_depth.GadgetText    = NULL;
3651   gad_depth.MutualExclude = 0;
3652   gad_depth.SpecialInfo   = NULL;
3653   gad_depth.GadgetID      = 0;
3654   gad_depth.UserData      = NULL;
3655 
3656   if( fullscr )
3657   {
3658     uint32 modeid, depth;
3659 
3660     modeid = IP96->p96BestModeIDTags( P96BIDTAG_NominalWidth,   800,
3661                                       P96BIDTAG_NominalHeight,  600,
3662                                       P96BIDTAG_FormatsAllowed, RGBFF_R8G8B8|
3663                                                                 RGBFF_B8G8R8|
3664                                                                 RGBFF_A8R8G8B8|
3665                                                                 RGBFF_A8B8G8R8|
3666                                                                 RGBFF_R8G8B8A8|
3667                                                                 RGBFF_B8G8R8A8|
3668                                                                 RGBFF_R5G6B5|
3669                                                                 RGBFF_R5G6B5PC|
3670                                                                 RGBFF_R5G5B5|
3671                                                                 RGBFF_R5G5B5PC|
3672                                                                 RGBFF_B5G6R5PC|
3673                                                                 RGBFF_B5G5R5PC,
3674                                       TAG_DONE );
3675     if( modeid == INVALID_ID )
3676     {
3677       printf( "Unable to get a suitable screenmode. Falling back to windowed mode...\n" );
3678       fullscr = FALSE;
3679     } else {
3680 
3681       depth = IP96->p96GetModeIDAttr( modeid, P96IDA_DEPTH );
3682 
3683       scr = IIntuition->OpenScreenTags( NULL,
3684         SA_Width,     800,
3685         SA_Height,    600,
3686         SA_Depth,     depth,
3687         SA_Title,     "HivelyTracker",
3688         SA_ShowTitle, FALSE,
3689         SA_DisplayID, modeid,
3690         SA_Pens,      -1,
3691         TAG_DONE );
3692       if( !scr )
3693       {
3694         printf( "Unable to open screen. Falling back to windowed mode...\n" );
3695         fullscr = FALSE;
3696       }
3697     }
3698   }
3699 
3700   mainwin = IIntuition->OpenWindowTags( NULL,
3701     WA_Width,       800,
3702     WA_Height,      600,
3703     WA_Borderless,  TRUE,
3704     WA_ScreenTitle, "HivelyTracker (c)2013 IRIS & Up Rough! - http://www.uprough.net - http://www.hivelytracker.co.uk",
3705     WA_RMBTrap,     TRUE,
3706     WA_IDCMP,       IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY|IDCMP_GADGETUP|IDCMP_EXTENDEDMOUSE,
3707     WA_Activate,    TRUE,
3708     WA_Gadgets,     fullscr ? NULL : &gad_drag,
3709     fullscr ? WA_CustomScreen : TAG_IGNORE, scr,
3710     WA_Backdrop,    fullscr,
3711     TAG_DONE );
3712   if( !mainwin )
3713   {
3714     printf( "Unable to open main window!\n" );
3715     return FALSE;
3716   }
3717 
3718 #endif // __SDL_WRAPPER__
3719 
3720   memset(&mainbm, 0, sizeof(mainbm));
3721   mainbm.w = 800;
3722   mainbm.h = 600;
3723 #ifndef __SDL_WRAPPER__
3724   memcpy(&mainbm.rp, mainwin->RPort, sizeof(struct RastPort));
3725   mainbm.bm = mainwin->RPort->BitMap;
3726 #else
3727   mainbm.srf = ssrf;
3728 #endif
3729 
3730   prefbm.w = 400;
3731   prefbm.h = 300;
3732 
3733   if( !gui_open_skin_images() )
3734   {
3735     printf( "Error loading skin. Reverting to SIDMonster-Light...\n" );
3736     strcpy( skindir, "Skins/SIDMonster-Light" );
3737     if( !gui_open_skin_images() ) return FALSE;
3738   }
3739 
3740   if( !make_image( &bitmaps[BM_POSED],      POSED_W+8, POSED_H ) )  return FALSE;
3741   if( !make_image( &bitmaps[BM_TRACKED],    TRACKED_W+8, TRACKED_H ) ) return FALSE;
3742   if( !make_image( &bitmaps[BM_TRACKBAR],   768, 20 ) )  return FALSE;
3743   if( !make_image( &bitmaps[BM_PERF],       PERF_W, PERF_H ) ) return FALSE;
3744   if( !make_image( &bitmaps[BM_INSLIST],    INSLIST_W, INSLIST_H ) ) return FALSE;
3745   if( !make_image( &bitmaps[BM_INSLISTB],   INSLSTB_W, INSLSTB_H ) ) return FALSE;
3746 #ifdef __SDL_WRAPPER__
3747   if( !make_image( &prefbm, 408, 308 ) ) return FALSE;
3748   prefbm.offx = 4;
3749   prefbm.offy = 4;
3750 #endif
3751 
3752 #ifndef __SDL_WRAPPER__
3753   fixfont = IDiskfont->OpenDiskFont( &fixfontattr );
3754   if( !fixfont )
3755   {
3756     printf( "Unable to open '%s'\n", fixfontattr.ta_Name );
3757     return FALSE;
3758   }
3759 
3760   sfxfont = IDiskfont->OpenDiskFont( &sfxfontattr );
3761   if( !sfxfont )
3762   {
3763     printf( "Unable to open '%s'\n", sfxfontattr.ta_Name );
3764     return FALSE;
3765   }
3766 
3767   prpfont = IDiskfont->OpenDiskFont( &prpfontattr );
3768   if( !prpfont )
3769   {
3770     printf( "Unable to open '%s'\n", prpfontattr.ta_Name );
3771     return FALSE;
3772   }
3773 #else
3774   fixttf = TTF_OpenFont(fixfontname, 14);
3775   if( !fixttf )
3776   {
3777     printf( "Unable to open '%s'\n", fixfontname );
3778     return FALSE;
3779   }
3780 
3781   sfxttf = TTF_OpenFont(sfxfontname, 12);
3782   if( !sfxttf )
3783   {
3784     printf( "Unable to open '%s'\n", sfxfontname );
3785     return FALSE;
3786   }
3787 
3788   prpttf = TTF_OpenFont(prpfontname, 14);
3789   if( !prpttf )
3790   {
3791     printf( "Unable to open '%s'\n", prpfontname );
3792     return FALSE;
3793   }
3794 #endif
3795 
3796   set_font(&bitmaps[BM_POSED], FONT_SFX, TRUE);
3797   set_pens(&bitmaps[BM_POSED], PAL_BACK, PAL_BACK);
3798   fillrect_xy(&bitmaps[BM_POSED], 0, 0, POSED_MX, POSED_MY);
3799   set_font(&bitmaps[BM_TRACKED], FONT_FIX, TRUE);
3800   set_pens(&bitmaps[BM_TRACKED], PAL_BACK, PAL_BACK);
3801   fillrect_xy(&bitmaps[BM_TRACKED], 0, 0, TRACKED_MX, TRACKED_MY);
3802   set_font(&bitmaps[BM_PERF], FONT_FIX, TRUE);
3803   set_pens(&bitmaps[BM_PERF], PAL_BACK, PAL_BACK);
3804   set_font(&bitmaps[BM_INSLIST], FONT_FIX, TRUE);
3805   set_pens(&bitmaps[BM_INSLIST], PAL_BACK, PAL_BACK);
3806   fillrect_xy(&bitmaps[BM_INSLIST], 0, 0, INSLIST_MX, TRACKED_MY);
3807   set_font(&bitmaps[BM_INSLISTB], FONT_FIX, TRUE);
3808   set_pens(&bitmaps[BM_INSLISTB], PAL_BACK, PAL_BACK);
3809   fillrect_xy(&bitmaps[BM_INSLISTB], 0, 0, INSLIST_MX, TRACKED_MY);
3810 
3811   for( i=0; i<8; i++ )
3812   {
3813     ttab[i].tune = NULL;
3814     ttab[i].zone = -1;
3815   }
3816 
3817   zn_close  = gui_add_zone( &zones[0], &numzones, MAX_ZONES, 0, 0, 24, 24 );
3818 
3819   if( fullscr )
3820     zn_scrdep = gui_add_zone( &zones[0], &numzones, MAX_ZONES, 776, 0, 24, 24 );
3821 
3822   for( i=0; i<6; i++ )
3823     zn_mute[i] = gui_add_zone( &zones[0], &numzones, MAX_ZONES, TRACKED_X+20+66+i*120, TRACKED_Y-22, 14, 19 );
3824 
3825 #ifndef __SDL_WRAPPER__
3826   mainwin_sig = (1L<<mainwin->UserPort->mp_SigBit);
3827   gui_sigs    = mainwin_sig | gui_tick_sig;
3828 #endif
3829 
3830   for( i=0; i<16; i++ )
3831     bbank[i].zone = gui_add_zone( &zones[0], &numzones, MAX_ZONES, (i&3)*80+256, (i>>2)*24, 80, 24 );
3832   for( i=0; i<12; i++ )
3833     tbank[i].zone = gui_add_zone( &zones[0], &numzones, MAX_ZONES, 744, 120+200+i*23, 52, 23 );
3834 
3835   posed_lasttune  = NULL;
3836   posed_lastposnr = -1;
3837 
3838   gui_set_nbox( &trk_nb[NB_POSNR],        75, 132,      58, 16, 0, 999, 0, "%03d", NBF_ENABLED|NBF_UDDURINGPLAY );
3839   gui_set_nbox( &trk_nb[NB_LENGTH],       75, 132+20*1, 58, 16, 1, 999, 0, "%03d", NBF_ENABLED|NBF_UDDURINGPLAY );
3840   gui_set_nbox( &trk_nb[NB_RESPOS],       75, 132+20*2, 58, 16, 0, 999, 0, "%03d", NBF_ENABLED|NBF_UDDURINGPLAY );
3841   gui_set_nbox( &trk_nb[NB_TRKLEN],       75, 132+20*3, 58, 16, 1,  64, 0, " %02d", NBF_ENABLED );
3842   gui_set_nbox( &trk_nb[NB_SSNR],         75, 132+20*4, 58, 16, 0, 255, 0, "%03d", NBF_ENABLED );
3843   gui_set_nbox( &trk_nb[NB_CURSS],        75, 132+20*5, 58, 16, 0, 255, 0, "%03d", NBF_ENABLED );
3844   gui_set_nbox( &trk_nb[NB_SSPOS],        75, 132+20*6, 58, 16, 0, 999, 0, "%03d", NBF_ENABLED );
3845 
3846   gui_set_nbox( &trk_nb[NB_CHANS],       219, 132,      58, 16, 4, MAX_CHANNELS, 0, " %02d", NBF_ENABLED );
3847   gui_set_nbox( &trk_nb[NB_MIXG],        219, 132+20*1, 58, 16, 0, 200, 0, "%03d", NBF_ENABLED|NBF_UDDURINGPLAY );
3848   gui_set_nbox( &trk_nb[NB_SPEEDMULT],   219, 132+20*2, 58, 16, 1,   4, 0, " %02d", NBF_ENABLED );
3849   gui_set_nbox( &trk_nb[NB_DRUMPADMODE], 219, 132+20*3, 58, 16, 0,   1, 0,      "", NBF_ENABLED|NBF_ONOFF|NBF_UDDURINGPLAY );
3850 
3851   gui_set_nbox( &ins_nb[INB_INS],     9,  128,      58, 16, 0,  63, 0, " %02d", NBF_ENABLED|NBF_UDDURINGPLAY );
3852 
3853   gui_set_nbox( &ins_nb[INB_VOL],     72, 142+20*1, 58, 16, 0,  64, 0, " %02d", NBF_ENABLED );
3854   gui_set_nbox( &ins_nb[INB_WAVELEN], 72, 142+20*2, 58, 16, 0,   5, 0, " %02X", NBF_ENABLED|NBF_WAVELEN );
3855 
3856   gui_set_nbox( &ins_nb[INB_ATTACK],  72, 160+20*3, 58, 16, 1, 255, 0, "%03d", NBF_ENABLED );
3857   gui_set_nbox( &ins_nb[INB_AVOL],    72, 160+20*4, 58, 16, 0,  64, 0, " %02d", NBF_ENABLED );
3858   gui_set_nbox( &ins_nb[INB_DECAY],   72, 160+20*5, 58, 16, 1, 255, 0, "%03d", NBF_ENABLED );
3859   gui_set_nbox( &ins_nb[INB_DVOL],    72, 160+20*6, 58, 16, 0,  64, 0, " %02d", NBF_ENABLED );
3860   gui_set_nbox( &ins_nb[INB_SUSTAIN], 72, 160+20*7, 58, 16, 1, 255, 0, "%03d", NBF_ENABLED );
3861   gui_set_nbox( &ins_nb[INB_RELEASE], 72, 160+20*8, 58, 16, 1, 255, 0, "%03d", NBF_ENABLED );
3862   gui_set_nbox( &ins_nb[INB_RVOL],    72, 160+20*9, 58, 16, 0,  64, 0, " %02d", NBF_ENABLED );
3863 
3864   gui_set_nbox( &ins_nb[INB_VIBDELAY],72, 178+20*10, 58, 16, 0, 255, 0, "%03d", NBF_ENABLED );
3865   gui_set_nbox( &ins_nb[INB_VIBDEPTH],72, 178+20*11, 58, 16, 0,  15, 0, " %02d", NBF_ENABLED );
3866   gui_set_nbox( &ins_nb[INB_VIBSPEED],72, 178+20*12, 58, 16, 0,  63, 0, " %02d", NBF_ENABLED );
3867 
3868   gui_set_nbox( &ins_nb[INB_SQRLOWER],72, 196+20*13, 58, 16, 1,  63, 0, " %02d", NBF_ENABLED );
3869   gui_set_nbox( &ins_nb[INB_SQRUPPER],72, 196+20*14, 58, 16, 1,  63, 0, " %02d", NBF_ENABLED );
3870   gui_set_nbox( &ins_nb[INB_SQRSPEED],72, 196+20*15, 58, 16, 0, 127, 0, "%03d", NBF_ENABLED );
3871 
3872   gui_set_nbox( &ins_nb[INB_FLTLOWER],72, 214+20*16, 58, 16, 1,  63, 0, " %02d", NBF_ENABLED );
3873   gui_set_nbox( &ins_nb[INB_FLTUPPER],72, 214+20*17, 58, 16, 1,  63, 0, " %02d", NBF_ENABLED );
3874   gui_set_nbox( &ins_nb[INB_FLTSPEED],72, 214+20*18, 58, 16, 0, 127, 0, "%03d", NBF_ENABLED );
3875 
3876   gui_set_nbox( &ins_nb[INB_PERFSPEED], 208, 142+20*1, 58, 16, 0, 255, 0, "%03d", NBF_ENABLED );
3877   gui_set_nbox( &ins_nb[INB_PERFLEN],   208, 142+20*2, 58, 16, 0, 255, 0, "%03d", NBF_ENABLED );
3878   gui_set_nbox( &ins_nb[INB_HARDCUT],   208, 142+20*3, 58, 16, 0,   7, 0, "  %01d", NBF_ENABLED );
3879   gui_set_nbox( &ins_nb[INB_RELCUT],    208, 142+20*4, 58, 16, 0,   1, 0, "  %01d", NBF_ENABLED|NBF_ONOFF );
3880 
3881   gui_set_tbox( &tbx[TB_SONGNAME], 298, 152, POSED_W, NULL, 127, TBF_ENABLED|TBF_VISIBLE, PN_TRACKER );
3882   gui_set_tbox( &tbx[TB_INSNAME],  115, 128, 148, NULL, 127, TBF_ENABLED|TBF_VISIBLE, PN_INSED );
3883   gui_set_tbox( &tbx[TB_INSNAME2], INSLIST_X+17, INSLIST_Y, INSLIST_W-17, NULL, 127, TBF_ENABLED, PN_TRACKER );
3884 
3885   gui_setup_trkbbank( 0 );
3886   gui_setup_buttonbank( 0 );
3887   if( IExec->GetHead(rp_tunelist) )
3888     gui_set_various_things( (struct ahx_tune *)IExec->GetHead(rp_tunelist) );
3889   gui_render_everything();
3890   gui_render_tunepanel( TRUE );
3891 
3892   cz_lmb = -1;
3893   cz_rmb = -1;
3894 
3895   return TRUE;
3896 }
3897 
gui_init(void)3898 BOOL gui_init( void )
3899 {
3900   gui_savethem = FALSE;
3901 
3902 #ifndef __SDL_WRAPPER__
3903   iev.ie_Class    = IECLASS_RAWKEY;
3904   iev.ie_SubClass = 0;
3905   strcpy( fixfontname, "Bitstream Vera Sans Mono.font" );
3906   strcpy( sfxfontname, "Bitstream Vera Sans Mono.font" );
3907   strcpy( prpfontname, "Bitstream Vera Sans.font" );
3908 #else
3909 #ifdef __APPLE__
3910   osxGetResourcesPath(fixfontname, "DejaVuSansMono.ttf");
3911   osxGetResourcesPath(sfxfontname, "DejaVuSansMono.ttf");
3912   osxGetResourcesPath(prpfontname, "DejaVuSans.ttf");
3913 #elif defined(__HAIKU__)
3914   strcpy( fixfontname, "/boot/system/data/fonts/ttfonts/DejaVuSansMono.ttf" );
3915   strcpy( sfxfontname, "/boot/system/data/fonts/ttfonts/DejaVuSansMono.ttf" );
3916   strcpy( prpfontname, "/boot/system/data/fonts/ttfonts/DejaVuSans.ttf" );
3917 #else
3918   strcpy( fixfontname, "ttf/DejaVuSansMono.ttf" );
3919   strcpy( sfxfontname, "ttf/DejaVuSansMono.ttf" );
3920   strcpy( prpfontname, "ttf/DejaVuSans.ttf" );
3921 #endif
3922 #endif
3923 
3924   strcpy( skinext,     ".png" );
3925 
3926 #ifndef __SDL_WRAPPER__
3927   if( !getLibIFace( &IntuitionBase, "intuition.library",    51, &IIntuition ) ) return FALSE;
3928   if( !getLibIFace( &GfxBase,       "graphics.library",     51, &IGraphics ) )  return FALSE;
3929   if( !getLibIFace( &P96Base,       "Picasso96API.library",  2, &IP96) )        return FALSE;
3930   if( !getLibIFace( &DataTypesBase, "datatypes.library",    51, &IDataTypes ) ) return FALSE;
3931   if( !getLibIFace( &DiskfontBase,  "diskfont.library",     51, &IDiskfont ) )  return FALSE;
3932   if( !getLibIFace( &AslBase,       "asl.library",          51, &IAsl) )        return FALSE;
3933   if( !getLibIFace( &KeymapBase,    "keymap.library",       51, &IKeymap) )     return FALSE;
3934   if( !getLibIFace( &RequesterBase, "requester.class",      51, &IRequester ) ) return FALSE;
3935 
3936   gui_tick_signum = IExec->AllocSignal( -1 );
3937   if( gui_tick_signum == -1 )
3938   {
3939     printf( "Unable to allocate signal\n" );
3940     return FALSE;
3941   }
3942   gui_tick_sig = (1L<<gui_tick_signum);
3943 
3944   ins_lreq = IAsl->AllocAslRequestTags( ASL_FileRequest,
3945                ASLFR_TitleText,     "Load Instrument",
3946                ASLFR_InitialDrawer, instdir,
3947                ASLFR_DoSaveMode,    FALSE,
3948                ASLFR_RejectIcons,   TRUE,
3949                TAG_DONE );
3950   if( !ins_lreq )
3951   {
3952     printf( "Error allocating Asl request\n" );
3953     return FALSE;
3954   }
3955 
3956   ins_sreq = IAsl->AllocAslRequestTags( ASL_FileRequest,
3957                ASLFR_TitleText,     "Save Instrument",
3958                ASLFR_InitialDrawer, instdir,
3959                ASLFR_DoSaveMode,    TRUE,
3960                ASLFR_RejectIcons,   TRUE,
3961                TAG_DONE );
3962   if( !ins_sreq )
3963   {
3964     printf( "Error allocating Asl request\n" );
3965     return FALSE;
3966   }
3967 
3968   sng_lreq = IAsl->AllocAslRequestTags( ASL_FileRequest,
3969                ASLFR_TitleText,     "Load Song",
3970                ASLFR_InitialDrawer, songdir,
3971                ASLFR_DoSaveMode,    FALSE,
3972                ASLFR_RejectIcons,   TRUE,
3973                TAG_DONE );
3974   if( !sng_lreq )
3975   {
3976     printf( "Error allocating Asl request\n" );
3977     return FALSE;
3978   }
3979 
3980   sng_sreq = IAsl->AllocAslRequestTags( ASL_FileRequest,
3981                ASLFR_TitleText,     songdir,
3982                ASLFR_InitialDrawer, "Songs",
3983                ASLFR_DoSaveMode,    TRUE,
3984                ASLFR_RejectIcons,   TRUE,
3985                TAG_DONE );
3986   if( !sng_sreq )
3987   {
3988     printf( "Error allocating Asl request\n" );
3989     return FALSE;
3990   }
3991 
3992   dir_req  = IAsl->AllocAslRequestTags( ASL_FileRequest,
3993                ASLFR_DoSaveMode,    FALSE,
3994                ASLFR_DrawersOnly,   TRUE,
3995                TAG_DONE );
3996   if( !ins_lreq )
3997   {
3998     printf( "Error allocating Asl request\n" );
3999     return FALSE;
4000   }
4001 #endif
4002 
4003   if( !gui_open() ) return FALSE;
4004 
4005   gui_savethem = TRUE;
4006 
4007   return TRUE;
4008 }
4009 
gui_press_bbank(struct buttonbank * bbnk,int32 nb,int32 z,int32 button)4010 void gui_press_bbank( struct buttonbank *bbnk, int32 nb, int32 z, int32 button )
4011 {
4012   int32 i;
4013 
4014   for( i=0; i<nb; i++ )
4015     if( z == bbnk[i].zone )
4016       break;
4017 
4018   if( i == nb )
4019     return;
4020 
4021   switch( button )
4022   {
4023     case 0:
4024       if( bbnk[i].action == BBA_NOTHING )
4025         return;
4026       break;
4027     case 1:
4028       if( bbnk[i].raction == BBA_NOTHING )
4029         return;
4030       break;
4031   }
4032 
4033   // Gahhh. I suck. But i can't be bothered to fix
4034   // this now.
4035   if( bbnk == &bbank[0] )
4036     put_partbitmap( BM_BUTBANKP, (i&3)*80, (i>>2)*24, (i&3)*80+256, (i>>2)*24, 80, 24 );
4037   if( bbnk == &tbank[0] )
4038     put_partbitmap( BM_TRKBANKP, 0, i*23, 744, 120+200+i*23, 52, 23 );
4039 
4040   if( bbnk[i].name == NULL ) return;
4041 
4042   set_font(&mainbm, FONT_PRP, FALSE);
4043   set_fpen(&mainbm, PAL_BTNSHADOW);
4044   printstr(&mainbm, bbnk[i].name, bbnk[i].x+bbnk[i].xo+1, bbnk[i].y+5);
4045   set_fpen(&mainbm, PAL_BTNTEXT);
4046   printstr(&mainbm, bbnk[i].name, bbnk[i].x+bbnk[i].xo, bbnk[i].y+4);
4047 }
4048 
gui_release_bbank(struct buttonbank * bbnk,int32 nb,int32 z,int32 button)4049 void gui_release_bbank( struct buttonbank *bbnk, int32 nb, int32 z, int32 button )
4050 {
4051   int32 i;
4052 
4053   for( i=0; i<nb; i++ )
4054     if( z == bbnk[i].zone )
4055       break;
4056 
4057   if( i == nb )
4058     return;
4059 
4060   switch( button )
4061   {
4062     case 0:
4063       if( bbnk[i].action == BBA_NOTHING )
4064         return;
4065       break;
4066     case 1:
4067       if( bbnk[i].raction == BBA_NOTHING )
4068         return;
4069       break;
4070   }
4071 
4072   if( bbnk == &bbank[0] )
4073     put_partbitmap( BM_BUTBANKR, (i&3)*80, (i>>2)*24, (i&3)*80+256, (i>>2)*24, 80, 24 );
4074   if( bbnk == &tbank[0] )
4075     put_partbitmap( BM_TRKBANKR, 0, i*23, 744, 120+200+i*23, 52, 23 );
4076 
4077   if( bbnk[i].name == NULL ) return;
4078 
4079   set_font(&mainbm, FONT_PRP, FALSE);
4080   set_fpen(&mainbm, PAL_BTNSHADOW);
4081   printstr(&mainbm, bbnk[i].name, bbnk[i].x+bbnk[i].xo+1, bbnk[i].y+5);
4082   set_fpen(&mainbm, PAL_BTNTEXT);
4083   printstr(&mainbm, bbnk[i].name, bbnk[i].x+bbnk[i].xo, bbnk[i].y+4);
4084 }
4085 
gui_copyposregion(struct ahx_tune * at,BOOL cutting)4086 void gui_copyposregion( struct ahx_tune *at, BOOL cutting )
4087 {
4088   int32 i, j, size;
4089   uint8 *ptr;
4090 
4091   // Calculate the size of the region to copy
4092   size = ((at->at_cbpmarkrgt-at->at_cbpmarklft)+1) *    /* Channels */
4093          ((at->at_cbpmarkbot-at->at_cbpmarktop)+1) *    /* Rows */
4094          2;
4095 
4096   if( cbpbuf == NULL )
4097   {
4098     cbpbuf  = IExec->AllocVecTags( size, TAG_DONE );
4099     if( cbpbuf == NULL ) return;
4100     cbpblen = size;
4101   }
4102 
4103   if( cbpblen < size )
4104   {
4105     IExec->FreeVec( cbpbuf );
4106     cbpblen = 0;
4107     cbpbuf  = IExec->AllocVecTags( size, TAG_DONE );
4108     if( cbpbuf == NULL ) return;
4109     cbpblen = size;
4110   }
4111 
4112   cbplcol = at->at_cbpmarklftcol;
4113   cbprcol = at->at_cbpmarkrgtcol;
4114   cbpchns = (at->at_cbpmarkrgt-at->at_cbpmarklft)+1;
4115   cbprows = (at->at_cbpmarkbot-at->at_cbpmarktop)+1;
4116 
4117   if( cutting ) setbefore_posregion( at, at->at_cbpmarklft, at->at_cbpmarktop, cbpchns, cbprows );
4118 
4119   ptr = cbpbuf;
4120   for( i=at->at_cbpmarktop; i<=at->at_cbpmarkbot; i++ )
4121   {
4122     for( j=at->at_cbpmarklft; j<=at->at_cbpmarkrgt; j++ )
4123     {
4124       *(ptr++) = at->at_Positions[i].pos_Track[j];
4125       *(ptr++) = at->at_Positions[i].pos_Transpose[j];
4126       if( cutting )
4127       {
4128         if(( j>at->at_cbpmarklft ) || ( cbplcol == 0 )) at->at_Positions[i].pos_Track[j]     = 0;
4129         if(( j<at->at_cbpmarkrgt ) || ( cbprcol != 0 )) at->at_Positions[i].pos_Transpose[j] = 0;
4130       }
4131     }
4132   }
4133 
4134   if( cutting ) setafter_posregion( at, at->at_cbpmarklft, at->at_cbpmarktop, cbpchns, cbprows );
4135 }
4136 
gui_pasteposregion(struct ahx_tune * at)4137 void gui_pasteposregion( struct ahx_tune *at )
4138 {
4139   int32 i, j, pos, lch;
4140   uint8 *ptr;
4141 
4142   if( cbpbuf == NULL ) return;
4143   if( ( cbpchns == 0 ) || ( cbprows == 0 ) ) return;
4144 
4145   pos = at->at_PosNr;
4146   lch = at->at_posed_curs/5 + at->at_curlch;
4147 
4148   setbefore_posregion( at, lch, pos, cbpchns, cbprows );
4149 
4150   ptr = cbpbuf;
4151   for( i=0; i<cbprows; i++ )
4152   {
4153     if( (i+pos) > 999 ) break;
4154     for( j=0; j<cbpchns; j++ )
4155     {
4156       if( (lch+j) >= at->at_Channels ) break;
4157       if( ( j > 0 ) || ( cbplcol == 0 ) )
4158         at->at_Positions[pos+i].pos_Track[lch+j] = *(ptr++);
4159       else
4160         ptr++;
4161       if( ( j < (cbpchns-1) ) || ( cbprcol == 1 ) )
4162         at->at_Positions[pos+i].pos_Transpose[lch+j] = *(ptr++);
4163       else
4164         ptr++;
4165     }
4166   }
4167 
4168   setafter_posregion( at, lch, pos, cbpchns, cbprows );
4169 
4170   at->at_modified = TRUE;
4171 }
4172 
gui_copyregion(int16 track,int16 start,int16 end,int16 toclip,BOOL cutting)4173 void gui_copyregion( int16 track, int16 start, int16 end, int16 toclip, BOOL cutting )
4174 {
4175   int32 i;
4176 
4177   for( i=start; i<=end; i++ )
4178   {
4179     if( toclip & CBF_NOTES )
4180     {
4181       cb_content[i-start].stp_Note       = curtune->at_Tracks[track][i].stp_Note;
4182       cb_content[i-start].stp_Instrument = curtune->at_Tracks[track][i].stp_Instrument;
4183       if( cutting )
4184       {
4185         curtune->at_Tracks[track][i].stp_Note       = 0;
4186         curtune->at_Tracks[track][i].stp_Instrument = 0;
4187       }
4188     }
4189 
4190     if( toclip & CBF_CMD1 )
4191     {
4192       cb_content[i-start].stp_FX         = curtune->at_Tracks[track][i].stp_FX;
4193       cb_content[i-start].stp_FXParam    = curtune->at_Tracks[track][i].stp_FXParam;
4194       if( cutting )
4195       {
4196         curtune->at_Tracks[track][i].stp_FX         = 0;
4197         curtune->at_Tracks[track][i].stp_FXParam    = 0;
4198       }
4199     }
4200 
4201     if( toclip & CBF_CMD2 )
4202     {
4203       cb_content[i-start].stp_FXb        = curtune->at_Tracks[track][i].stp_FXb;
4204       cb_content[i-start].stp_FXbParam   = curtune->at_Tracks[track][i].stp_FXbParam;
4205       if( cutting )
4206       {
4207         curtune->at_Tracks[track][i].stp_FXb        = 0;
4208         curtune->at_Tracks[track][i].stp_FXbParam   = 0;
4209       }
4210     }
4211   }
4212 
4213   cb_contains = toclip;
4214   cb_length   = (end-start)+1;
4215 }
4216 
gui_paste(struct ahx_tune * at,int16 track,int16 pastemask)4217 void gui_paste( struct ahx_tune *at, int16 track, int16 pastemask )
4218 {
4219   int32 i;
4220 
4221   if( at == NULL ) return;
4222   if( track == -1 ) return;
4223   if( cb_length == 0 ) return;
4224 
4225   pastemask &= cb_contains;  // Only the bits in both
4226   if( pastemask == 0 ) return;
4227 
4228   for( i=0; i<cb_length; i++ )
4229   {
4230     if( (i+at->at_NoteNr) >= at->at_TrackLength )
4231       break;
4232 
4233     if( pastemask & CBF_NOTES )
4234     {
4235       at->at_Tracks[track][i+at->at_NoteNr].stp_Note       = cb_content[i].stp_Note;
4236       at->at_Tracks[track][i+at->at_NoteNr].stp_Instrument = cb_content[i].stp_Instrument;
4237     }
4238 
4239     if( pastemask & CBF_CMD1 )
4240     {
4241       at->at_Tracks[track][i+at->at_NoteNr].stp_FX         = cb_content[i].stp_FX;
4242       at->at_Tracks[track][i+at->at_NoteNr].stp_FXParam    = cb_content[i].stp_FXParam;
4243     }
4244 
4245     if( pastemask & CBF_CMD2 )
4246     {
4247       at->at_Tracks[track][i+at->at_NoteNr].stp_FXb        = cb_content[i].stp_FXb;
4248       at->at_Tracks[track][i+at->at_NoteNr].stp_FXbParam   = cb_content[i].stp_FXbParam;
4249     }
4250   }
4251 
4252   at->at_NoteNr = (at->at_NoteNr+i)%at->at_TrackLength;
4253   at->at_modified = TRUE;
4254 }
4255 
optimise(struct ahx_tune * from,struct ahx_tune * to,BOOL optimise_more)4256 BOOL optimise( struct ahx_tune *from, struct ahx_tune *to, BOOL optimise_more )
4257 {
4258   int32 op_pos, op_chan, op_track, op_trans;
4259   int32 thistrans, i, j, k;
4260   int32 imap[64], icare[64], ins, topins;
4261   BOOL usedzero, carenote;
4262 
4263   for( i=0; i<63; i++ )
4264     imap[i] = 0;
4265 
4266   IExec->CopyMem( from->at_Name, to->at_Name, 128 );
4267   strncat( to->at_Name, "[opt]", 128 );
4268   to->at_Name[127]       = 0;
4269   to->at_Restart         = from->at_Restart;
4270   to->at_PositionNr      = from->at_PositionNr;
4271   to->at_SpeedMultiplier = from->at_SpeedMultiplier;
4272   to->at_TrackLength     = from->at_TrackLength;
4273   to->at_SubsongNr       = from->at_SubsongNr;
4274   to->at_Stereo          = from->at_Stereo;
4275   IExec->CopyMem( from->at_Subsongs, to->at_Subsongs, 256*2 );
4276   to->at_Channels        = from->at_Channels;
4277   to->at_mixgain         = from->at_mixgain;
4278   to->at_mixgainP        = from->at_mixgainP;
4279 
4280   topins = 1;
4281   usedzero = FALSE;
4282   carenote = TRUE;
4283 
4284   // Loop through all the positions
4285   for( op_pos=0; op_pos<from->at_PositionNr; op_pos++ )
4286   {
4287     // Loop through all the channels
4288     for( op_chan=0; op_chan<from->at_Channels; op_chan++ )
4289     {
4290       op_track = from->at_Positions[op_pos].pos_Track[op_chan];
4291       op_trans = from->at_Positions[op_pos].pos_Transpose[op_chan];
4292 
4293       // Find a track already present that matches
4294       // this one
4295       for( i=0; i<to->at_TrackNr; i++ )
4296       {
4297         thistrans = optimise_more ? 10000 : 0;
4298         for( j=0; j<from->at_TrackLength; j++ )
4299         {
4300           // Map the instrument
4301           ins = from->at_Tracks[op_track][j].stp_Instrument;
4302           if( ins > 0 )
4303           {
4304             if( imap[ins] == 0 )
4305             {
4306               to->at_Instruments[topins] = from->at_Instruments[ins];
4307               imap[ins] = topins++;
4308 
4309               icare[ins] = FALSE;
4310               for( k=0; k<from->at_Instruments[ins].ins_PList.pls_Length; k++ )
4311               {
4312                 if( ( from->at_Instruments[ins].ins_PList.pls_Entries[k].ple_Note != 0 ) &&
4313                     ( from->at_Instruments[ins].ins_PList.pls_Entries[k].ple_Fixed == 0 ) )
4314                 {
4315                   icare[ins] = TRUE;
4316                   break;
4317                 }
4318               }
4319             }
4320             carenote = icare[ins];
4321             ins = imap[ins];
4322           }
4323 
4324           // Compare it
4325           if( to->at_Tracks[i][j].stp_Instrument != ins ) break;
4326           if( to->at_Tracks[i][j].stp_FX         != from->at_Tracks[op_track][j].stp_FX      )  break;
4327           if( to->at_Tracks[i][j].stp_FXParam    != from->at_Tracks[op_track][j].stp_FXParam )  break;
4328           if( to->at_Tracks[i][j].stp_FXb        != from->at_Tracks[op_track][j].stp_FXb      ) break;
4329           if( to->at_Tracks[i][j].stp_FXbParam   != from->at_Tracks[op_track][j].stp_FXbParam ) break;
4330 
4331           if( from->at_Tracks[op_track][j].stp_Note != 0 )
4332           {
4333             if( to->at_Tracks[i][j].stp_Note == 0 ) break;
4334 
4335             if( ( ins == 0 ) || ( carenote ) )
4336             {
4337               if( thistrans != 10000 )
4338               {
4339                 if( (to->at_Tracks[i][j].stp_Note-from->at_Tracks[op_track][j].stp_Note) != thistrans )
4340                   break;
4341               } else {
4342                 thistrans = to->at_Tracks[i][j].stp_Note - from->at_Tracks[op_track][j].stp_Note;
4343                 if( ( (thistrans+op_trans) < -128 ) ||
4344                     ( (thistrans+op_trans) > 127 ) )
4345                   break;
4346               }
4347             }
4348           } else {
4349             if( to->at_Tracks[i][j].stp_Note != 0 ) break;
4350           }
4351         }
4352 
4353         // Found a match?
4354         if( j == from->at_TrackLength )
4355           break;
4356       }
4357 
4358       if( i == to->at_TrackNr )
4359       {
4360         for( j=0; j<from->at_TrackLength; j++ )
4361         {
4362           // Map the instrument
4363           ins = from->at_Tracks[op_track][j].stp_Instrument;
4364           if( ins > 0 )
4365           {
4366             if( imap[ins] == 0 )
4367             {
4368               to->at_Instruments[topins] = from->at_Instruments[ins];
4369               imap[ins] = topins++;
4370 
4371               icare[ins] = FALSE;
4372               for( k=0; k<from->at_Instruments[ins].ins_PList.pls_Length; k++ )
4373               {
4374                 if( ( from->at_Instruments[ins].ins_PList.pls_Entries[k].ple_Note != 0 ) &&
4375                     ( from->at_Instruments[ins].ins_PList.pls_Entries[k].ple_Fixed == 0 ) )
4376                 {
4377                   icare[ins] = TRUE;
4378                   break;
4379                 }
4380               }
4381 
4382             }
4383             ins = imap[ins];
4384           }
4385 
4386           to->at_Tracks[i][j].stp_Instrument = ins;
4387           to->at_Tracks[i][j].stp_Note       = from->at_Tracks[op_track][j].stp_Note;
4388           to->at_Tracks[i][j].stp_FX         = from->at_Tracks[op_track][j].stp_FX;
4389           to->at_Tracks[i][j].stp_FXParam    = from->at_Tracks[op_track][j].stp_FXParam;
4390           to->at_Tracks[i][j].stp_FXb        = from->at_Tracks[op_track][j].stp_FXb;
4391           to->at_Tracks[i][j].stp_FXbParam   = from->at_Tracks[op_track][j].stp_FXbParam;
4392         }
4393         to->at_TrackNr++;
4394         thistrans = 0;
4395       }
4396 
4397       if( thistrans == 10000 ) thistrans = 0;
4398 
4399       to->at_Positions[op_pos].pos_Track[op_chan]     = i;
4400       to->at_Positions[op_pos].pos_Transpose[op_chan] = op_trans-thistrans;
4401 
4402       if( i == 0 ) usedzero = TRUE;
4403     }
4404   }
4405 
4406   return usedzero;
4407 }
4408 
gui_check_bbank(struct buttonbank * bbnk,int32 nb,int32 z,int32 button)4409 BOOL gui_check_bbank( struct buttonbank *bbnk, int32 nb, int32 z, int32 button )
4410 {
4411   int32 i, j, b, l;
4412   int32 chan, track;
4413 #ifndef __SDL_WRAPPER__
4414   BPTR lock, olddir;
4415 #else
4416   char *gfname;
4417 #endif
4418   BOOL ok, optimise_more;
4419   struct ahx_tune *at;
4420   struct ahx_step tstp;
4421   TEXT tmp[256];
4422   BOOL cutting;
4423   int32 toclip;
4424 
4425   for( i=0; i<nb; i++ )
4426     if( z == bbnk[i].zone )
4427       break;
4428 
4429   if( i == nb )
4430     return FALSE;
4431 
4432   if( button == 0 )
4433     b = bbnk[i].action;
4434   else
4435     b = bbnk[i].raction;
4436 
4437   chan = track = -1;
4438   if( curtune )
4439   {
4440     chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
4441     track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
4442   }
4443 
4444   cutting = FALSE;
4445   toclip = 0;
4446   optimise_more = FALSE;
4447 
4448   switch( b )
4449   {
4450     case BBA_ABOUT:
4451       about_toggle();
4452       break;
4453 
4454     case BBA_ZAP:
4455 #ifndef __SDL_WRAPPER__
4456       switch( gui_req( REQIMAGE_QUESTION, "Zap!", "What would you like to Zap?", "Everything|Song|Tracks|Positions|Instruments|Oops! Nothing!" ) )
4457       {
4458         case 1: // Everything
4459           rp_clear_tune( curtune );
4460           gui_render_tunepanel( TRUE );
4461           break;
4462 
4463         case 2: // Song
4464           rp_zap_tracks( curtune );
4465           rp_zap_positions( curtune );
4466           free_undolists( curtune );
4467           gui_render_tunepanel( TRUE );
4468           break;
4469 
4470         case 3: // Tracks
4471           rp_zap_tracks( curtune );
4472           free_undolists( curtune );
4473           gui_render_tunepanel( TRUE );
4474           break;
4475 
4476         case 4: // Positions
4477           rp_zap_positions( curtune );
4478           free_undolists( curtune );
4479           gui_render_tunepanel( TRUE );
4480           break;
4481 
4482         case 5:  // Instruments
4483           rp_zap_instruments( curtune );
4484           free_undolists( curtune );
4485           gui_render_tunepanel( TRUE );
4486           break;
4487       }
4488 #else
4489       gui_setup_buttonbank( 1 );
4490       gui_render_main_buttonbank();
4491 #endif
4492       break;
4493 
4494     case BBA_ZAP_SONG:
4495       rp_zap_tracks( curtune );
4496       rp_zap_positions( curtune );
4497       free_undolists( curtune );
4498       gui_render_tunepanel( TRUE );
4499       gui_setup_buttonbank( 0 );
4500       gui_render_main_buttonbank();
4501       break;
4502 
4503     case BBA_ZAP_TRACKS:
4504       rp_zap_tracks( curtune );
4505       free_undolists( curtune );
4506       gui_render_tunepanel( TRUE );
4507       gui_setup_buttonbank( 0 );
4508       gui_render_main_buttonbank();
4509       break;
4510 
4511     case BBA_ZAP_POSNS:
4512       rp_zap_positions( curtune );
4513       free_undolists( curtune );
4514       gui_render_tunepanel( TRUE );
4515       gui_setup_buttonbank( 0 );
4516       gui_render_main_buttonbank();
4517       break;
4518 
4519     case BBA_ZAP_INSTRS:
4520       rp_zap_instruments( curtune );
4521       free_undolists( curtune );
4522       gui_render_tunepanel( TRUE );
4523       gui_setup_buttonbank( 0 );
4524       gui_render_main_buttonbank();
4525       break;
4526 
4527     case BBA_ZAP_ALL:
4528       rp_clear_tune( curtune );
4529       gui_render_tunepanel( TRUE );
4530       gui_setup_buttonbank( 0 );
4531       gui_render_main_buttonbank();
4532       break;
4533 
4534     case BBA_BACK:
4535       gui_setup_buttonbank( 0 );
4536       gui_render_main_buttonbank();
4537       break;
4538 
4539     case BBA_UNDO:
4540       rp_stop();
4541       curtune->at_doing = D_IDLE;
4542       undo( curtune );
4543       gui_render_wavemeter();
4544       break;
4545 
4546     case BBA_REDO:
4547       rp_stop();
4548       curtune->at_doing = D_IDLE;
4549       redo( curtune );
4550       gui_render_wavemeter();
4551       break;
4552 
4553     case BBA_AUTOGAIN:
4554       rp_stop();
4555       gui_render_wavemeter();
4556       curtune->at_doing = D_IDLE;
4557 
4558       for( j=0; j<curtune->at_Channels; j++ )
4559       {
4560         curtune->at_Voices[j].vc_SetTrackOn = 1;
4561         curtune->at_Voices[j].vc_TrackOn = 1;
4562       }
4563 
4564       bbank[i].name = "Wait...";
4565       gui_render_main_buttonbank();
4566 
4567       l = rp_find_loudest( curtune );
4568       if( l > 0 )
4569         l = 3276700/l;
4570       else
4571         l = 100;
4572 
4573       if( l > 200 ) l = 200;
4574       modify_tune_b( curtune, UNT_MIXGAIN, l );
4575       curtune->at_mixgain  = (l*256)/100;
4576 
4577       rp_init_subsong( curtune, 0 );
4578 
4579       gui_set_various_things( curtune );
4580       gui_render_posed( FALSE );
4581       gui_render_tracked( TRUE );
4582 
4583       bbank[i].name = "Autogain";
4584       gui_render_main_buttonbank();
4585 
4586       break;
4587 
4588     case BBA_INSEDIT:
4589       curtune->at_idoing = D_IDLE;
4590       if( curtune->at_curpanel == PN_TRACKER )
4591         curtune->at_curpanel = PN_INSED;
4592       else
4593         curtune->at_curpanel = PN_TRACKER;
4594 
4595       gui_render_tunepanel( TRUE );
4596       break;
4597 
4598     case BBA_NEWTAB:
4599       at = rp_new_tune( TRUE );
4600       if( at )
4601       {
4602         curtune = at;
4603         gui_set_various_things( at );
4604         gui_render_tabs();
4605         gui_render_tunepanel( TRUE );
4606       }
4607       break;
4608 
4609     case BBA_OPTIMISE_MORE:
4610       optimise_more = TRUE;
4611     case BBA_OPTIMISE:
4612       at = rp_new_tune( TRUE );
4613       if( at )
4614       {
4615         at->at_TrackNr = 1; // Try and use track 0 as the empty one
4616         if( !optimise( curtune, at, optimise_more ) )
4617         {
4618           rp_clear_tune( at );
4619           at->at_TrackNr = 0;
4620           optimise( curtune, at, optimise_more );
4621         }
4622 
4623         at->at_doing    = D_IDLE;
4624         at->at_editing  = E_TRACK;
4625         at->at_idoing   = D_IDLE;
4626         curtune = at;
4627         gui_set_various_things( at );
4628         gui_render_tabs();
4629         gui_render_tunepanel( TRUE );
4630       }
4631       break;
4632 
4633     case BBA_CLONETAB:
4634       at = rp_new_tune( TRUE );
4635       if( at )
4636       {
4637         IExec->CopyMem( &curtune->at_Name[0], &at->at_Name[0], sizeof( struct ahx_tune ) - offsetof( struct ahx_tune, at_Name ) );
4638         at->at_doing    = D_IDLE;
4639         at->at_editing  = E_TRACK;
4640         at->at_idoing   = D_IDLE;
4641         curtune = at;
4642         gui_set_various_things( at );
4643         gui_render_tabs();
4644         gui_render_tunepanel( TRUE );
4645       }
4646       break;
4647 
4648     case BBA_LOADINS:
4649       if( curtune == NULL ) break;
4650 
4651       if( curtune->at_curins == 0 )
4652         curtune->at_curins = 1;
4653 
4654       rp_stop();
4655       gui_render_tracked( TRUE );  // Kill the VUMeters
4656       gui_render_wavemeter();
4657       curtune->at_doing = D_IDLE;
4658 
4659 #ifndef __SDL_WRAPPER__
4660       ok = IAsl->AslRequestTags( ins_lreq,
4661         ASLFR_Window,      mainwin,
4662         ASLFR_SleepWindow, TRUE,
4663         TAG_DONE );
4664       if( !ok ) break;
4665 
4666       lock = IDOS->Lock( ins_lreq->fr_Drawer, ACCESS_READ );
4667       olddir = IDOS->CurrentDir( lock );
4668 
4669       rp_load_ins( ins_lreq->fr_File, curtune, curtune->at_curins );
4670 
4671       IDOS->CurrentDir( olddir );
4672       IDOS->UnLock( lock );
4673 #else
4674       if (!(gfname = filerequester("Load instrument", reminstdir, "", FR_INSLOAD))) break;
4675       setpathpart(reminstdir, gfname);
4676       rp_load_ins( gfname, curtune, curtune->at_curins );
4677       free(gfname);
4678 #endif
4679       gui_set_various_things( curtune );
4680       if( curtune->at_curpanel == PN_TRACKER )
4681       {
4682         gui_render_inslist( TRUE );
4683       } else {
4684         gui_render_perf( curtune, &curtune->at_Instruments[curtune->at_curins], TRUE );
4685         gui_render_tbox( &mainbm, &tbx[TB_INSNAME] );
4686         gui_render_inslistb( TRUE );
4687       }
4688       break;
4689 
4690     case BBA_SAVEAHX:
4691       if( curtune == NULL ) break;
4692 
4693       rp_stop();
4694       gui_render_tracked( TRUE );  // Kill the VUMeters
4695       gui_render_wavemeter();
4696       curtune->at_doing = D_IDLE;
4697 
4698       i = rp_ahx_test( curtune );
4699       if( i != 0 )
4700       {
4701         TEXT wtxt[4096];
4702 
4703         sprintf( wtxt, "'%s' uses the following HivelyTracker specific features:\n\n", curtune->at_Name );
4704 
4705         if( i & SWF_MANYCHANS ) strcat( wtxt, "* More than 4 channels\n" );
4706         if( i & SWF_DOUBLECMD ) strcat( wtxt, "* Notes with 2 commands\n" );
4707         if( i & SWF_NEWINSCMD ) strcat( wtxt, "* Instruments with commands other than 1,2,3,4,5,C & F\n" );
4708         if( i & SWF_PANCMD )    strcat( wtxt, "* 7xx panning command\n" );
4709         if( i & SWF_EFXCMD )    strcat( wtxt, "* EFx command\n" );
4710 
4711         strcat( wtxt, "\nSaving as AHX would strip these out. Are you sure?" );
4712 
4713         if( gui_req( REQIMAGE_WARNING, "HivelyTracker", wtxt, "_OK|_Noooo!" ) == 0 )
4714           break;
4715       }
4716 
4717       strcpy( tmp, "AHX." );
4718       strcat( tmp, curtune->at_Name );
4719 
4720 #ifndef __SDL_WRAPPER__
4721       ok = IAsl->AslRequestTags( sng_sreq,
4722         ASLFR_Window,      mainwin,
4723         ASLFR_InitialFile, tmp,
4724         ASLFR_SleepWindow, TRUE,
4725         TAG_DONE );
4726       if( !ok ) break;
4727 
4728       lock = IDOS->Lock( sng_sreq->fr_Drawer, ACCESS_READ );
4729       olddir = IDOS->CurrentDir( lock );
4730 
4731       rp_save_ahx( sng_sreq->fr_File, curtune );
4732 
4733       if( i == 0 )
4734         curtune->at_modified = FALSE;
4735 
4736       IDOS->CurrentDir( olddir );
4737       IDOS->UnLock( lock );
4738 #else
4739       if (!(gfname = filerequester("Save AHX module", remsongdir, "", FR_AHXSAVE))) break;
4740       setpathpart(remsongdir, gfname);
4741       rp_save_ahx( gfname, curtune );
4742       free(gfname);
4743       if( i == 0 )
4744         curtune->at_modified = FALSE;
4745 #endif
4746       break;
4747 
4748     case BBA_SAVEHVL:
4749       if( curtune == NULL ) break;
4750 
4751       rp_stop();
4752       gui_render_tracked( TRUE );  // Kill the VUMeters
4753       gui_render_wavemeter();
4754       curtune->at_doing = D_IDLE;
4755 
4756       strcpy( tmp, "HVL." );
4757       strcat( tmp, curtune->at_Name );
4758 
4759 #ifndef __SDL_WRAPPER__
4760       ok = IAsl->AslRequestTags( sng_sreq,
4761         ASLFR_Window,      mainwin,
4762         ASLFR_InitialFile, tmp,
4763         ASLFR_SleepWindow, TRUE,
4764         TAG_DONE );
4765       if( !ok ) break;
4766 
4767       lock = IDOS->Lock( sng_sreq->fr_Drawer, ACCESS_READ );
4768       olddir = IDOS->CurrentDir( lock );
4769 
4770       rp_save_hvl( sng_sreq->fr_File, curtune );
4771 
4772       curtune->at_modified = FALSE;
4773 
4774       IDOS->CurrentDir( olddir );
4775       IDOS->UnLock( lock );
4776 #else
4777       if (!(gfname = filerequester("Save HVL module", remsongdir, "", FR_HVLSAVE))) break;
4778       setpathpart(remsongdir, gfname);
4779       rp_save_hvl( gfname, curtune );
4780       free(gfname);
4781       curtune->at_modified = FALSE;
4782 #endif
4783       break;
4784 
4785     case BBA_SAVEINS:
4786       if( curtune == NULL ) break;
4787 
4788       rp_stop();
4789       gui_render_tracked( TRUE );  // Kill the VUMeters
4790       gui_render_wavemeter();
4791       curtune->at_doing = D_IDLE;
4792 
4793       strcpy( tmp, "INS." );
4794       strcat( tmp, curtune->at_Instruments[curtune->at_curins].ins_Name );
4795 
4796 #ifndef __SDL_WRAPPER__
4797       ok = IAsl->AslRequestTags( ins_sreq,
4798         ASLFR_Window,      mainwin,
4799         ASLFR_InitialFile, tmp,
4800         ASLFR_SleepWindow, TRUE,
4801         TAG_DONE );
4802       if( !ok ) break;
4803 
4804       lock = IDOS->Lock( ins_sreq->fr_Drawer, ACCESS_READ );
4805       olddir = IDOS->CurrentDir( lock );
4806 
4807       rp_save_ins( ins_sreq->fr_File, curtune, curtune->at_curins );
4808       gui_set_various_things( curtune );
4809 
4810       IDOS->CurrentDir( olddir );
4811       IDOS->UnLock( lock );
4812 #else
4813       if (!(gfname = filerequester("Save instrument", reminstdir, "", FR_INSSAVE))) break;
4814       setpathpart(reminstdir, gfname);
4815       rp_save_ins( gfname, curtune, curtune->at_curins );
4816       free(gfname);
4817       gui_set_various_things( curtune );
4818 #endif
4819       break;
4820 
4821     case BBA_LOADTUNE:
4822       if( ( curtune != NULL ) && ( curtune->at_modified ) )
4823         if( gui_req( REQIMAGE_QUESTION, "HivelyTracker", "This song has been modified. Continue?", "_Yep!|Arrgh.. _No!" ) == 0 )
4824           break;
4825 
4826 #ifndef __SDL_WRAPPER__
4827       ok = IAsl->AslRequestTags( sng_lreq,
4828         ASLFR_Window,      mainwin,
4829         ASLFR_SleepWindow, TRUE,
4830         TAG_DONE );
4831       if( !ok ) break;
4832 #else
4833       if (!(gfname = filerequester("Load song", remsongdir, "", FR_MODLOAD))) break;
4834       setpathpart(remsongdir, gfname);
4835 #endif
4836       rp_stop();
4837       gui_render_tracked( TRUE );  // Kill the VUMeters
4838       gui_render_wavemeter();
4839       if( curtune ) curtune->at_doing = D_IDLE;
4840 
4841 #ifndef __SDL_WRAPPER__
4842       lock = IDOS->Lock( sng_lreq->fr_Drawer, ACCESS_READ );
4843       olddir = IDOS->CurrentDir( lock );
4844 
4845       at = rp_load_tune( sng_lreq->fr_File, curtune );
4846       if( at ) curtune = at;
4847 
4848       IDOS->CurrentDir( olddir );
4849       IDOS->UnLock( lock );
4850 #else
4851       at = rp_load_tune( gfname, curtune );
4852       free( gfname );
4853       if( at ) curtune = at;
4854 #endif
4855       if( at ) gui_set_rempos( at );
4856       gui_render_tabs();
4857       gui_render_tunepanel( TRUE );
4858       break;
4859 
4860     case BBA_CONTPOS:
4861     case BBA_PLAYPOS:
4862       if( curtune == NULL )
4863         break;
4864 
4865       curtune->at_doing = D_IDLE;
4866       if( rp_play_pos( curtune, b == BBA_CONTPOS ? TRUE : FALSE ) )
4867         curtune->at_doing = D_PLAYING;
4868       break;
4869 
4870     case BBA_CONTSONG:
4871     case BBA_PLAYSONG:
4872       if( curtune == NULL )
4873         break;
4874 
4875       curtune->at_doing = D_IDLE;
4876       if( rp_play_song( curtune, curtune->at_curss, b == BBA_CONTSONG ? TRUE : FALSE ) )
4877          curtune->at_doing = D_PLAYING;
4878       break;
4879 
4880     case BBA_STOP:
4881       rp_stop();
4882       gui_render_tracked( TRUE );  // Kill the VUMeters
4883       gui_render_wavemeter();
4884       curtune->at_doing = D_IDLE;
4885       break;
4886 
4887     case BBA_PREFS:
4888 #ifndef __SDL_WRAPPER__
4889       if( prefwin )
4890         gui_close_prefs();
4891       else
4892         gui_open_prefs();
4893 #else
4894       gui_open_prefs();
4895 #endif
4896       break;
4897 
4898     case BBA_CUTTRK:
4899       cutting = TRUE;
4900     case BBA_COPYTRK:
4901       if( curtune->at_cbmarktrack != -1 )
4902       {
4903         gui_copyregion( curtune->at_cbmarktrack, curtune->at_cbmarkstartnote, curtune->at_cbmarkendnote, curtune->at_cbmarkbits, cutting );
4904         curtune->at_cbmarktrack = -1;
4905         if( curtune->at_curpanel == PN_TRACKER )
4906           gui_render_tracked( TRUE );
4907         break;
4908       }
4909 
4910       if( track == -1 ) break;
4911 
4912       if( button == 1 )
4913       {
4914         toclip = CBF_CMD1|CBF_CMD2;
4915       } else {
4916         if( qual & IEQUALIFIER_CONTROL )
4917           toclip = CBF_NOTES;
4918         else
4919           toclip = CBF_NOTES|CBF_CMD1|CBF_CMD2;
4920       }
4921 
4922       gui_copyregion( track, 0, curtune->at_TrackLength-1, toclip, cutting );
4923 
4924       if( curtune->at_curpanel == PN_TRACKER )
4925         gui_render_tracked( TRUE );
4926       break;
4927 
4928     case BBA_PASTE:
4929       if( curtune->at_cbmarktrack != -1 ) curtune->at_cbmarktrack = -1;
4930       if( track == -1 ) break;
4931 
4932       setbefore_track( curtune, track );
4933       gui_paste( curtune, track, CBF_NOTES|CBF_CMD1|CBF_CMD2 );
4934       setafter_track( curtune, track );
4935 
4936       if( curtune->at_curpanel == PN_TRACKER )
4937         gui_render_tracked( TRUE );
4938       break;
4939 
4940     case BBA_NOTEUP:
4941       if( track == -1 ) break;
4942 
4943       setbefore_track( curtune, track );
4944 
4945       for( i=0; i<curtune->at_TrackLength; i++ )
4946       {
4947         if( ( curtune->at_Tracks[track][i].stp_Note > 0 ) &&
4948             ( curtune->at_Tracks[track][i].stp_Note < 60 ) )
4949           curtune->at_Tracks[track][i].stp_Note++;
4950       }
4951 
4952       setafter_track( curtune, track );
4953 
4954       if( curtune->at_curpanel == PN_TRACKER )
4955         gui_render_tracked( TRUE );
4956       break;
4957 
4958     case BBA_NOTEDN:
4959       if( track == -1 ) break;
4960 
4961       setbefore_track( curtune, track );
4962 
4963       for( i=0; i<curtune->at_TrackLength; i++ )
4964       {
4965         if( curtune->at_Tracks[track][i].stp_Note > 1 )
4966           curtune->at_Tracks[track][i].stp_Note--;
4967       }
4968 
4969       setafter_track( curtune, track );
4970 
4971       if( curtune->at_curpanel == PN_TRACKER )
4972         gui_render_tracked( TRUE );
4973       break;
4974 
4975     case BBA_REVERSE:
4976       if( track == -1 ) break;
4977 
4978       setbefore_track( curtune, track );
4979 
4980       l = curtune->at_TrackLength>>1;
4981       b = curtune->at_TrackLength-1;
4982       for( i=0; i<l; i++ )
4983       {
4984         tstp = curtune->at_Tracks[track][i];
4985         curtune->at_Tracks[track][i] = curtune->at_Tracks[track][b-i];
4986         curtune->at_Tracks[track][b-i] = tstp;
4987       }
4988 
4989       setafter_track( curtune, track );
4990 
4991       if( curtune->at_curpanel == PN_TRACKER )
4992         gui_render_tracked( TRUE );
4993       break;
4994 
4995     case BBA_SCRLUP:
4996       if( track == -1 ) break;
4997 
4998       setbefore_track( curtune, track );
4999 
5000       tstp = curtune->at_Tracks[track][0];
5001 
5002       for( i=1; i<curtune->at_TrackLength; i++ )
5003         curtune->at_Tracks[track][i-1] = curtune->at_Tracks[track][i];
5004 
5005       curtune->at_Tracks[track][curtune->at_TrackLength-1] = tstp;
5006 
5007       setafter_track( curtune, track );
5008 
5009       if( curtune->at_curpanel == PN_TRACKER )
5010         gui_render_tracked( TRUE );
5011       break;
5012 
5013     case BBA_SCRLDN:
5014       if( track == -1 ) break;
5015 
5016       setbefore_track( curtune, track );
5017 
5018       tstp = curtune->at_Tracks[track][curtune->at_TrackLength-1];
5019 
5020       for( i=curtune->at_TrackLength-1; i>=0; i-- )
5021         curtune->at_Tracks[track][i] = curtune->at_Tracks[track][i-1];
5022 
5023       curtune->at_Tracks[track][0] = tstp;
5024 
5025       setafter_track( curtune, track );
5026 
5027       if( curtune->at_curpanel == PN_TRACKER )
5028         gui_render_tracked( TRUE );
5029       break;
5030   }
5031 
5032   return TRUE;
5033 }
5034 
gui_press_any_bbank(int32 z,int32 button)5035 void gui_press_any_bbank( int32 z, int32 button )
5036 {
5037   gui_press_bbank( &bbank[0], 16, z, button );
5038   if (curtune->at_curpanel == PN_TRACKER)
5039     gui_press_bbank( &tbank[0], 12, z, button );
5040 }
5041 
gui_release_any_bbank(int32 z,int32 button)5042 void gui_release_any_bbank( int32 z, int32 button )
5043 {
5044   gui_release_bbank( &bbank[0], 16, z, button );
5045   if (curtune->at_curpanel == PN_TRACKER)
5046     gui_release_bbank( &tbank[0], 12, z, button );
5047 }
5048 
gui_check_any_bbank(int32 z,int32 button)5049 BOOL gui_check_any_bbank( int32 z, int32 button )
5050 {
5051   if( gui_check_bbank( &bbank[0], 16, z, button ) ) return TRUE;
5052   if (curtune->at_curpanel == PN_TRACKER)
5053     if( gui_check_bbank( &tbank[0], 12, z, button ) ) return TRUE;
5054   return FALSE;
5055 }
5056 
gui_check_nbox_butpress(int16 x,int16 y)5057 BOOL gui_check_nbox_butpress( int16 x, int16 y )
5058 {
5059   int32 i, num;
5060   struct numberbox *nbp = NULL;
5061 
5062   if( curtune == NULL ) return FALSE;
5063 
5064   switch( curtune->at_curpanel )
5065   {
5066     case PN_TRACKER:
5067       nbp = &trk_nb[0];
5068       num = NB_END;
5069       break;
5070 
5071     case PN_INSED:
5072       nbp = &ins_nb[0];
5073       num = INB_END;
5074       break;
5075   }
5076 
5077   if( nbp == NULL ) return FALSE;
5078 
5079   for( i=0; i<num; i++ )
5080   {
5081     if( ( x >= nbp[i].x+nbp[i].w-28 ) && ( x < nbp[i].x+nbp[i].w-14 ) &&
5082         ( y >= nbp[i].y ) && ( y < nbp[i].y+nbp[i].h ) )
5083     {
5084       if( nbp[i].flags & NBF_ENABLED )
5085       {
5086         if( ( ( nbp[i].flags & NBF_UDDURINGPLAY ) == 0 ) &&
5087             ( curtune->at_doing == D_PLAYING ) )
5088             return FALSE;
5089 
5090         put_partbitmap( BM_PLUSMINUS, 0, 19, nbp[i].x+nbp[i].w-28, nbp[i].y-1, 14, 19 );
5091         nbp[i].pressed = 1;
5092       }
5093       return TRUE;
5094     }
5095 
5096     if( ( x >= nbp[i].x+nbp[i].w-14 ) && ( x < nbp[i].x+nbp[i].w ) &&
5097         ( y >= nbp[i].y ) && ( y < nbp[i].y+nbp[i].h ) )
5098     {
5099       if( nbp[i].flags & NBF_ENABLED )
5100       {
5101         if( ( ( nbp[i].flags & NBF_UDDURINGPLAY ) == 0 ) &&
5102             ( curtune->at_doing == D_PLAYING ) )
5103             return FALSE;
5104 
5105         put_partbitmap( BM_PLUSMINUS, 14, 19, nbp[i].x+nbp[i].w-14, nbp[i].y-1, 14, 19 );
5106         nbp[i].pressed = 2;
5107       }
5108       return TRUE;
5109     }
5110   }
5111 
5112   return FALSE;
5113 }
5114 
gui_check_nbox_butrelease(int16 x,int16 y)5115 BOOL gui_check_nbox_butrelease( int16 x, int16 y )
5116 {
5117   int32 i, num;
5118   BOOL ret;
5119   struct numberbox *nbp = NULL;
5120 
5121   if( curtune == NULL ) return FALSE;
5122 
5123   ret = FALSE;
5124   switch( curtune->at_curpanel )
5125   {
5126     case PN_TRACKER:
5127       nbp = &trk_nb[0];
5128       num = NB_END;
5129       break;
5130 
5131     case PN_INSED:
5132       nbp = &ins_nb[0];
5133       num = INB_END;
5134       break;
5135   }
5136 
5137   if( nbp == NULL ) return FALSE;
5138 
5139   for( i=0; i<num; i++ )
5140   {
5141     if( ( x >= nbp[i].x+nbp[i].w-28 ) && ( x < nbp[i].x+nbp[i].w-14 ) &&
5142         ( y >= nbp[i].y ) && ( y < nbp[i].y+nbp[i].h ) )
5143     {
5144       if( nbp[i].pressed == 1 )
5145       {
5146         if( qual & IEQUALIFIER_RBUTTON )
5147           nbp[i].cnum+=10;
5148         else
5149           nbp[i].cnum++;
5150         gui_update_from_nbox( curtune->at_curpanel, nbp, i );
5151         ret = TRUE;
5152       }
5153     }
5154 
5155     if( ( x >= nbp[i].x+nbp[i].w-14 ) && ( x < nbp[i].x+nbp[i].w ) &&
5156         ( y >= nbp[i].y ) && ( y < nbp[i].y+nbp[i].h ) )
5157     {
5158       if( nbp[i].pressed == 2 )
5159       {
5160         if( qual & IEQUALIFIER_RBUTTON )
5161           nbp[i].cnum-=10;
5162         else
5163           nbp[i].cnum--;
5164         gui_update_from_nbox( curtune->at_curpanel, nbp, i );
5165         ret = TRUE;
5166       }
5167     }
5168 
5169     if( nbp[i].pressed != 0 )
5170     {
5171       nbp[i].pressed = 0;
5172       put_partbitmap( BM_PLUSMINUS, 0, 0, nbp[i].x+nbp[i].w-28, nbp[i].y-1, 28, 19 );
5173     }
5174   }
5175 
5176   return ret;
5177 }
5178 
gui_check_ptbox_press(int16 x,int16 y)5179 BOOL gui_check_ptbox_press( int16 x, int16 y )
5180 {
5181   int32 i;
5182 
5183 #ifndef __SDL_WRAPPER__
5184   // *sigh* i suck, i know i suck.
5185   x += pw_bl;
5186   y += pw_bt;
5187 #else
5188   if (!prefwin_open) return FALSE;
5189 #endif
5190 
5191   for( i=0; i<PTB_END; i++ )
5192   {
5193     if( ( x >= ptb[i].x ) && ( x < ptb[i].x+ptb[i].w ) &&
5194         ( y >= ptb[i].y ) && ( y < ptb[i].y+16 ) &&
5195         ( ptb[i].flags & TBF_ENABLED ) &&
5196         ( ptb[i].flags & TBF_VISIBLE ) &&
5197         ( ptb[i].content != NULL ) )
5198     {
5199       if( ( ptbx != NULL ) && ( ptbx != &ptb[i] ) )
5200       {
5201         ptbx->flags &= ~TBF_ACTIVE;
5202         gui_render_tbox( &prefbm, ptbx );
5203       }
5204       ptbx = &ptb[i];
5205 #ifdef __SDL_WRAPPER__
5206       SDL_EnableUNICODE(SDL_TRUE);
5207 #endif
5208       ptbx->flags |= TBF_ACTIVE;
5209       ptbx->cpos = ((x-ptbx->x)>>3)+ptbx->spos;
5210       gui_render_tbox( &prefbm, ptbx );
5211 #ifdef __SDL_WRAPPER__
5212       bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
5213 #endif
5214       return TRUE;
5215     }
5216   }
5217 
5218   return FALSE;
5219 }
5220 
gui_ptbox_finish_editing(void)5221 void gui_ptbox_finish_editing( void )
5222 {
5223   if( ptbx == NULL ) return;
5224 
5225   ptbx = NULL;
5226 #ifdef __SDL_WRAPPER__
5227   SDL_EnableUNICODE(SDL_FALSE);
5228 #endif
5229 }
5230 
gui_tbox_finish_editing(void)5231 void gui_tbox_finish_editing( void )
5232 {
5233   if( etbx == NULL ) return;
5234 
5235   if( etbx == &tbx[TB_SONGNAME] )
5236   {
5237     setafter_string( UNT_STRING_SONGNAME, curtune, etbx->content );
5238     gui_render_tabs();
5239   }
5240 
5241   if( etbx == &tbx[TB_INSNAME] )
5242   {
5243     setafter_string( UNT_STRING_INSNAME, curtune, etbx->content );
5244     gui_render_inslistb( TRUE );
5245   }
5246 
5247   if( etbx == &tbx[TB_INSNAME2] )
5248   {
5249     setafter_string( UNT_STRING_INSNAME2, curtune, etbx->content );
5250     tbx[TB_INSNAME2].flags &= ~TBF_VISIBLE;
5251     tbx[TB_INSNAME2].content = NULL;
5252     gui_render_inslist( TRUE );
5253   }
5254 
5255 #ifdef __SDL_WRAPPER__
5256   SDL_EnableUNICODE(SDL_FALSE);
5257 #endif
5258   etbx = NULL;
5259 }
5260 
gui_check_tbox_press(int16 x,int16 y)5261 BOOL gui_check_tbox_press( int16 x, int16 y )
5262 {
5263   int32 i;
5264   int16 panel;
5265 
5266   panel = PN_TRACKER;
5267   if( curtune )
5268     panel = curtune->at_curpanel;
5269 
5270   for( i=0; i<TB_END; i++ )
5271   {
5272     if( panel == tbx[i].inpanel )
5273     {
5274       if( ( x >= tbx[i].x ) && ( x < tbx[i].x+tbx[i].w ) &&
5275           ( y >= tbx[i].y ) && ( y < tbx[i].y+16 ) &&
5276           ( tbx[i].flags & TBF_ENABLED ) &&
5277           ( tbx[i].flags & TBF_VISIBLE ) &&
5278           ( tbx[i].content != NULL ) )
5279       {
5280         if( ( etbx != NULL ) && ( etbx != &tbx[i] ) )
5281         {
5282           etbx->flags &= ~TBF_ACTIVE;
5283           gui_render_tbox( &mainbm, etbx );
5284           gui_tbox_finish_editing();
5285         }
5286         setbefore_string( curtune, tbx[i].content );
5287         etbx = &tbx[i];
5288         etbx->flags |= TBF_ACTIVE;
5289         etbx->cpos = ((x-etbx->x)>>3)+etbx->spos;
5290         gui_render_tbox( &mainbm, etbx );
5291 #ifdef __SDL_WRAPPER__
5292         SDL_EnableUNICODE(SDL_TRUE);
5293 #endif
5294         return TRUE;
5295       }
5296     }
5297   }
5298 
5299   return FALSE;
5300 }
5301 
gui_press_mute(int32 zone)5302 void gui_press_mute( int32 zone )
5303 {
5304   int32 i, mch;
5305 
5306   if( curtune == NULL ) return;
5307   if( curtune->at_curpanel != PN_TRACKER ) return;
5308 
5309   mch=0;
5310   for( i=0; i<6; i++ )
5311     if( zone == zn_mute[i] ) break;
5312 
5313   if( i == 6 ) return;
5314 
5315   mch = i+curtune->at_curlch;
5316 
5317   if( curtune->at_Voices[mch].vc_SetTrackOn )
5318     put_partbitmap( BM_CHANMUTE, 0, 19, zones[zone].x, zones[zone].y, 14, 19 );
5319   else
5320     put_partbitmap( BM_CHANMUTE, 0,  0, zones[zone].x, zones[zone].y, 14, 19 );
5321 }
5322 
gui_release_mute(int32 zone)5323 void gui_release_mute( int32 zone )
5324 {
5325   int32 i, mch;
5326 
5327   if( curtune == NULL ) return;
5328   if( curtune->at_curpanel != PN_TRACKER ) return;
5329 
5330   mch=0;
5331   for( i=0; i<6; i++ )
5332     if( zone == zn_mute[i] ) break;
5333 
5334   if( i == 6 ) return;
5335 
5336   mch = i+curtune->at_curlch;
5337 
5338   if( curtune->at_Voices[mch].vc_SetTrackOn )
5339     put_partbitmap( BM_CHANMUTE, 0,  0, zones[zone].x, zones[zone].y, 14, 19 );
5340   else
5341     put_partbitmap( BM_CHANMUTE, 0, 19, zones[zone].x, zones[zone].y, 14, 19 );
5342 }
5343 
gui_check_mute(int32 zone)5344 BOOL gui_check_mute( int32 zone )
5345 {
5346   int32 i, mch;
5347 
5348   if( curtune == NULL ) return FALSE;
5349   if( curtune->at_curpanel != PN_TRACKER ) return FALSE;
5350 
5351   mch=0;
5352   for( i=0; i<6; i++ )
5353     if( zone == zn_mute[i] ) break;
5354 
5355   if( i == 6 ) return FALSE;
5356 
5357   mch = i+curtune->at_curlch;
5358 
5359   curtune->at_Voices[mch].vc_SetTrackOn ^= 1;
5360   curtune->at_Voices[mch].vc_TrackOn = curtune->at_Voices[mch].vc_SetTrackOn;
5361 
5362   if( curtune->at_Voices[mch].vc_SetTrackOn )
5363     put_partbitmap( BM_CHANMUTE, 0,  0, zones[zone].x, zones[zone].y, 14, 19 );
5364   else
5365     put_partbitmap( BM_CHANMUTE, 0, 19, zones[zone].x, zones[zone].y, 14, 19 );
5366 
5367   return TRUE;
5368 }
5369 
gui_check_rmb_mute(int32 zone)5370 BOOL gui_check_rmb_mute( int32 zone )
5371 {
5372   int32 i, mch;
5373 
5374   if( curtune == NULL ) return FALSE;
5375   if( curtune->at_curpanel != PN_TRACKER ) return FALSE;
5376 
5377   mch=0;
5378   for( i=0; i<6; i++ )
5379     if( zone == zn_mute[i] ) break;
5380 
5381   if( i == 6 ) return FALSE;
5382 
5383   mch = i+curtune->at_curlch;
5384 
5385   // Already solo'd?
5386   for( i=0; i<curtune->at_Channels; i++ )
5387   {
5388     if( i == mch )
5389     {
5390       if( curtune->at_Voices[i].vc_SetTrackOn == 0 ) break;
5391     } else {
5392       if( curtune->at_Voices[i].vc_SetTrackOn != 0 ) break;
5393     }
5394   }
5395 
5396   if( i == curtune->at_Channels )
5397   {
5398     // Already solo'd, so set all tracks on
5399     for( i=0; i<curtune->at_Channels; i++ )
5400       curtune->at_Voices[i].vc_SetTrackOn = 1;
5401   } else {
5402     // Not solo'd, so solo it
5403     for( i=0; i<curtune->at_Channels; i++ )
5404       curtune->at_Voices[i].vc_SetTrackOn = i==mch ? 1 : 0;
5405   }
5406 
5407   for( i=0; i<curtune->at_Channels; i++ )
5408   {
5409     curtune->at_Voices[i].vc_TrackOn = curtune->at_Voices[i].vc_SetTrackOn;
5410 
5411     if( ( i >= curtune->at_curlch ) && ( i < (curtune->at_curlch+6) ) )
5412     {
5413       zone = zn_mute[i-curtune->at_curlch];
5414       if( curtune->at_Voices[i].vc_SetTrackOn )
5415         put_partbitmap( BM_CHANMUTE, 0,  0, zones[zone].x, zones[zone].y, 14, 19 );
5416       else
5417         put_partbitmap( BM_CHANMUTE, 0, 19, zones[zone].x, zones[zone].y, 14, 19 );
5418     }
5419   }
5420 
5421   return TRUE;
5422 }
5423 
gui_maybe_quit(void)5424 BOOL gui_maybe_quit( void )
5425 {
5426   struct ahx_tune *at;
5427   BOOL anymod;
5428 
5429   anymod = FALSE;
5430 
5431   at = (struct ahx_tune *)IExec->GetHead(rp_tunelist);
5432   while( at )
5433   {
5434     if( at->at_modified )
5435     {
5436       anymod = TRUE;
5437       break;
5438     }
5439     at = (struct ahx_tune *)IExec->GetSucc(&at->at_ln);
5440   }
5441 
5442   if( anymod )
5443     return gui_req( REQIMAGE_QUESTION, "HivelyTracker", "One or more songs have been modified. Really quit?", "_Yep!|Arrgh.. _No!" );
5444 
5445   return gui_req( REQIMAGE_QUESTION, "HivelyTracker", "Are you sure you want to quit?", "_Yep!|Arrgh.. _No!" );
5446 }
5447 
gui_wheelybin(int16 mousex,int16 mousey,int16 wheeldir)5448 void gui_wheelybin( int16 mousex, int16 mousey, int16 wheeldir )
5449 {
5450   int32 i, chan;
5451   struct ahx_plsentry *cple;
5452   struct ahx_instrument *cins;
5453 
5454   if( wheeldir == 0 ) return;
5455   if( !curtune ) return;
5456 
5457   switch( curtune->at_curpanel )
5458   {
5459     case PN_TRACKER:
5460 
5461       // Check numberboxes
5462       for( i=0; i<NB_END; i++ )
5463       {
5464         if( ( mousex >= trk_nb[i].x ) &&
5465             ( mousex < (trk_nb[i].x+trk_nb[i].w ) ) &&
5466             ( mousey >= trk_nb[i].y ) &&
5467             ( mousey < (trk_nb[i].y+trk_nb[i].h ) ) )
5468           break;
5469       }
5470 
5471       if( i < NB_END )
5472       {
5473         if( trk_nb[i].flags & NBF_ENABLED )
5474         {
5475           if( ( ( trk_nb[i].flags & NBF_UDDURINGPLAY ) == 0 ) &&
5476               ( curtune->at_doing == D_PLAYING ) )
5477             return;
5478 
5479           trk_nb[i].cnum -= wheeldir;
5480           gui_update_from_nbox( curtune->at_curpanel, &trk_nb[0], i );
5481         }
5482         return;
5483       }
5484 
5485       if( ( mousey >= (TRACKED_Y-22) ) && ( mousey < TRACKED_Y ) &&
5486           ( mousex >= (TRACKED_X+24) ) && ( mousex < (TRACKED_X+TRACKED_W) ) )
5487       {
5488         i    = (mousex-(TRACKED_X+24)) % 120;
5489         chan = (mousex-(TRACKED_X+24)) / 120 + curtune->at_curlch;
5490 
5491         if( i < 78 ) return;
5492         if( chan >= curtune->at_Channels ) return;
5493 
5494         modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, curtune->at_Positions[curtune->at_PosNr].pos_Track[chan] - wheeldir );
5495         gui_render_posed( TRUE );
5496         gui_render_tracked( TRUE );
5497         return;
5498       }
5499 
5500       if( ( mousex >= TRACKED_X ) && ( mousex < (TRACKED_X+TRACKED_W) ) &&
5501           ( mousey >= TRACKED_Y ) && ( mousey < (TRACKED_Y+TRACKED_H) ) )
5502       {
5503         if( curtune->at_doing == D_PLAYING ) return;
5504 
5505         i = curtune->at_NoteNr + wheeldir;
5506         if( i <= 0 ) i = 0;
5507         if( i >= curtune->at_TrackLength ) i = curtune->at_TrackLength-1;
5508         curtune->at_NoteNr = i;
5509 
5510         gui_render_tracker( FALSE );
5511         return;
5512       }
5513 
5514       if( ( mousex >= POSED_X ) && ( mousex < POSED_X+POSED_W ) &&
5515           ( mousey >= POSED_Y ) && ( mousey < POSED_Y+POSED_H ) )
5516       {
5517         if( curtune->at_doing == D_PLAYING )
5518         {
5519           int16 next;
5520           if( curtune->at_NextPosNr == -1 )
5521             next = curtune->at_PosNr + wheeldir;
5522           else
5523             next = curtune->at_NextPosNr + wheeldir;
5524           if( next < 0 )   next = 0;
5525           if( next > 999 ) next = 999;
5526           curtune->at_NextPosNr = next;
5527         } else {
5528           curtune->at_PosNr += wheeldir;
5529           if( curtune->at_PosNr < 0 )   curtune->at_PosNr = 0;
5530           if( curtune->at_PosNr > 999 ) curtune->at_PosNr = 999;
5531         }
5532         gui_render_tracker( FALSE );
5533         return;
5534       }
5535 
5536       if( ( mousex >= INSLIST_X ) && ( mousex < (INSLIST_X+INSLIST_W) ) &&
5537           ( mousey >= INSLIST_Y ) && ( mousey < (INSLIST_Y+INSLIST_H) ) )
5538       {
5539         curtune->at_curins += wheeldir;
5540         if( curtune->at_curins < 1 ) curtune->at_curins = 1;
5541         if( curtune->at_curins > 63 ) curtune->at_curins = 63;
5542         gui_render_inslist( FALSE );
5543         gui_set_various_things( curtune );
5544       }
5545 
5546       break;
5547 
5548     case PN_INSED:
5549 
5550       // Check numberboxes
5551       for( i=0; i<INB_END; i++ )
5552       {
5553         if( ( mousex >= ins_nb[i].x ) &&
5554             ( mousex < (ins_nb[i].x+ins_nb[i].w ) ) &&
5555             ( mousey >= ins_nb[i].y ) &&
5556             ( mousey < (ins_nb[i].y+ins_nb[i].h ) ) )
5557           break;
5558       }
5559 
5560       if( i < INB_END )
5561       {
5562         if( ins_nb[i].flags & NBF_ENABLED )
5563         {
5564           if( ( ( ins_nb[i].flags & NBF_UDDURINGPLAY ) == 0 ) &&
5565               ( curtune->at_doing == D_PLAYING ) )
5566             return;
5567 
5568           ins_nb[i].cnum -= wheeldir;
5569           gui_update_from_nbox( curtune->at_curpanel, &ins_nb[0], i );
5570         }
5571         return;
5572       }
5573 
5574       cins = NULL;
5575       cple = NULL;
5576       if( curtune )
5577       {
5578         cins = &curtune->at_Instruments[curtune->at_curins];
5579         cple = &cins->ins_PList.pls_Entries[cins->ins_pcury];
5580       }
5581 
5582       if( ( cins != NULL ) &&
5583           ( mousex >= PERF_X ) && ( mousex < (PERF_X+PERF_W) ) &&
5584           ( mousey >= PERF_Y ) && ( mousey < (PERF_Y+PERF_H) ) )
5585       {
5586         cins->ins_pcury += wheeldir;
5587         gui_render_perf( curtune, cins, FALSE );
5588         return;
5589       }
5590 
5591       if( ( curtune != NULL ) &&
5592           ( mousex >= INSLSTB_X ) && ( mousex < (INSLSTB_X+INSLSTB_W) ) &&
5593           ( mousey >= INSLSTB_Y ) && ( mousey < (INSLSTB_Y+INSLSTB_H) ) )
5594       {
5595         curtune->at_curins += wheeldir;
5596         if( curtune->at_curins < 0 ) curtune->at_curins = 0;
5597         if( curtune->at_curins > 63 ) curtune->at_curins = 63;
5598         cins = &curtune->at_Instruments[curtune->at_curins];
5599         cple = &cins->ins_PList.pls_Entries[cins->ins_pcury];
5600         gui_set_various_things( curtune );
5601       }
5602 
5603       break;
5604   }
5605 }
5606 
gui_mouse_handler(int16 x,int16 y,uint32 code)5607 void gui_mouse_handler( int16 x, int16 y, uint32 code )
5608 {
5609   int32 i, j;
5610 
5611   switch( code )
5612   {
5613     case SELECTDOWN:
5614       if( gui_check_tbox_press( x, y ) ) return;
5615 
5616       if( etbx )
5617       {
5618         etbx->flags &= ~TBF_ACTIVE;
5619         gui_render_tbox( &mainbm, etbx );
5620         gui_tbox_finish_editing();
5621         return;
5622       }
5623 
5624       if( ( curtune ) && ( curtune->at_curpanel == PN_TRACKER ) )
5625       {
5626         if( ( x >= TRACKED_X ) && ( x < 744  ) &&
5627             ( y >= TRACKED_Y ) && ( y < TRACKED_Y+TRACKED_H ) )
5628         {
5629           curtune->at_editing = E_TRACK;
5630 
5631           if( ( curtune ) && ( x > (TRACKED_X+23) ) )
5632           {
5633             i = (x-(TRACKED_X+24)) >> 3;
5634             j = i % 15;
5635             i /= 15;
5636 
5637             switch( j )
5638             {
5639               case 0:
5640               case 1:
5641               case 2:
5642               case 3:
5643                 j = 0;
5644                 break;
5645               case 4:
5646                 j = 1;
5647                 break;
5648               case 5:
5649               case 6:
5650                 j = 2;
5651                 break;
5652               case 7:
5653                 j = 3;
5654                 break;
5655               case 8:
5656                 j = 4;
5657                 break;
5658               case 9:
5659               case 10:
5660                 j = 5;
5661                 break;
5662               case 11:
5663                 j = 6;
5664                 break;
5665               case 12:
5666                 j = 7;
5667                 break;
5668               case 13:
5669               case 14:
5670                 j = 8;
5671                 break;
5672             }
5673 
5674             if( i < curtune->at_Channels )
5675               curtune->at_tracked_curs = i*9+j;
5676           }
5677 
5678           gui_render_tracked( TRUE );
5679           gui_render_posed( TRUE );
5680           break;
5681         }
5682 
5683         if( ( x >= POSED_X ) && ( x < POSED_X+POSED_W ) &&
5684             ( y >= POSED_Y ) && ( y < POSED_Y+POSED_H ) )
5685         {
5686           curtune->at_editing = E_POS;
5687 
5688           if( ( curtune ) && ( x > (POSED_X+27) ) )
5689           {
5690             i = (x-(POSED_X+28)) / 7;
5691             j = i % 7;
5692             i /= 7;
5693 
5694             switch( j )
5695             {
5696               case 3:
5697                 j = 2;
5698                 break;
5699               case 4:
5700                 j = 3;
5701                 break;
5702               case 5:
5703               case 6:
5704                 j = 4;
5705                 break;
5706             }
5707 
5708             if( i < curtune->at_Channels )
5709               curtune->at_posed_curs = i*5+j;
5710           }
5711 
5712           gui_render_tracked( TRUE );
5713           gui_render_posed( TRUE );
5714           break;
5715         }
5716       }
5717 
5718       if( gui_check_nbox_butpress( x, y ) )
5719         break;
5720 
5721       cz_lmb = gui_get_zone( &zones[0], numzones, x, y );
5722       if( cz_lmb != -1 )
5723       {
5724         gui_press_mute( cz_lmb );
5725         gui_press_any_bbank( cz_lmb, 0 );
5726       }
5727       break;
5728     case SELECTUP:
5729       if( etbx != NULL ) break;
5730 
5731       if( gui_check_nbox_butrelease( x, y ) )
5732         break;
5733 
5734       if( cz_lmb != -1 )
5735       {
5736         gui_release_any_bbank( cz_lmb, 0 );
5737         gui_press_mute( cz_lmb );
5738       }
5739 
5740       if( ( cz_lmb != -1 ) && ( cz_lmb == gui_get_zone( &zones[0], numzones, x, y ) ) )
5741       {
5742         if( gui_check_mute( cz_lmb ) )
5743         {
5744           cz_lmb = -1;
5745           break;
5746         }
5747 
5748         if( gui_check_any_bbank( cz_lmb, 0 ) )
5749         {
5750           cz_lmb = -1;
5751           if( quitting ) return;
5752           break;
5753         }
5754 
5755         if( cz_lmb == zn_close )
5756         {
5757           // Close gadget
5758           quitting = gui_maybe_quit();
5759         } else if( cz_lmb == zn_scrdep ) {
5760 #ifndef __SDL_WRAPPER__
5761           if( scr ) IIntuition->ScreenToBack( scr );
5762 #endif
5763         } else {
5764 
5765           // Check for tab zones
5766           for( i=0; i<8; i++ )
5767           {
5768             if( cz_lmb == ttab[i].zone )
5769             {
5770               BOOL dorend;
5771 
5772               dorend = FALSE;
5773               if( x < (zones[ttab[i].zone].x+20) )
5774               {
5775                 if( ttab[i].tune->at_modified )
5776                   if( gui_req( REQIMAGE_QUESTION, "HivelyTracker", "This song has been modified. Continue?", "_Yep!|Arrgh.. _No!" ) == 0 )
5777                     break;
5778 
5779                 // Only one tune?
5780                 IExec->ObtainSemaphore( rp_list_ss );
5781                 if( IExec->GetSucc(IExec->GetHead(rp_tunelist)) == NULL )
5782                 {
5783                   rp_clear_tune( ttab[i].tune );
5784                   gui_set_various_things( ttab[i].tune );
5785                   dorend = TRUE;
5786                 } else {
5787                   rp_free_tune( ttab[i].tune );
5788                   if( curtune == ttab[i].tune )
5789                   {
5790                     curtune = (struct ahx_tune *)IExec->GetHead(rp_tunelist);
5791                     gui_set_various_things(curtune);
5792                   }
5793 
5794                   dorend = TRUE;
5795                 }
5796                 IExec->ReleaseSemaphore( rp_list_ss );
5797               } else {
5798                 if( ttab[i].tune != curtune )
5799                 {
5800                   curtune = ttab[i].tune;
5801                   dorend = TRUE;
5802                 }
5803               }
5804 
5805               if( dorend )
5806               {
5807                 gui_render_tabs();
5808                 gui_render_tunepanel( TRUE );
5809               }
5810               break;
5811             }
5812           }
5813 
5814         }
5815 
5816         cz_lmb = -1;
5817         break;
5818       }
5819 
5820       if( ( curtune ) && ( curtune->at_curpanel == PN_TRACKER ) )
5821       {
5822         if( ( x >= INSLIST_X ) && ( x < (INSLIST_X+INSLIST_W) ) &&
5823             ( y >= INSLIST_Y ) && ( y < (INSLIST_Y+INSLIST_H) ) )
5824         {
5825           int32 i;
5826 
5827           i = (y-(INSLIST_Y+5))/14;
5828           if( i < 0 ) i = 0;
5829           curtune->at_curins = i+curtune->at_topins;
5830           gui_render_inslist( FALSE );
5831           gui_set_various_things( curtune );
5832         }
5833       }
5834 
5835       if( ( curtune ) && ( curtune->at_curpanel == PN_INSED ) )
5836       {
5837         if( ( x >= INSLSTB_X ) && ( x < (INSLIST_X+INSLSTB_W) ) &&
5838             ( y >= INSLSTB_Y ) && ( y < (INSLIST_Y+INSLSTB_H) ) )
5839         {
5840           int32 i;
5841 
5842           i = (y-(INSLSTB_Y+4))>>4;
5843           if( i < 0 ) i = 0;
5844           curtune->at_curins = i+curtune->at_topinsb;
5845           gui_set_various_things( curtune );
5846         }
5847 
5848         if( ( x >= PERF_X ) && ( x < (PERF_X+PERF_W) ) &&
5849             ( y >= PERF_Y ) && ( y < (PERF_Y+PERF_H) ) )
5850         {
5851           int32 i;
5852           struct ahx_instrument *cins;
5853 
5854           cins = &curtune->at_Instruments[curtune->at_curins];
5855 
5856           i = (y-(PERF_Y+4))>>4;
5857           if( i < 0 ) i = 0;
5858           cins->ins_pcury = i+cins->ins_ptop;
5859           gui_set_various_things( curtune );
5860         }
5861       }
5862       break;
5863     case MENUDOWN:
5864       if( etbx != NULL ) break;
5865       cz_rmb = gui_get_zone( &zones[0], numzones, x, y );
5866       if( cz_rmb != -1 )
5867       {
5868         gui_press_any_bbank( cz_rmb, 1 );
5869         gui_press_mute( cz_rmb );
5870       }
5871       break;
5872     case MENUUP:
5873       if( etbx != NULL ) break;
5874 
5875       if( cz_rmb != -1 )
5876       {
5877         gui_release_any_bbank( cz_rmb, 1 );
5878         gui_release_mute( cz_rmb );
5879       }
5880 
5881       if( ( cz_rmb != -1 ) && ( cz_rmb == gui_get_zone( &zones[0], numzones, x, y ) ) )
5882       {
5883         if( gui_check_rmb_mute( cz_rmb ) )
5884         {
5885           cz_rmb = -1;
5886           break;
5887         }
5888 
5889         if( gui_check_any_bbank( cz_rmb, 1 ) )
5890         {
5891           cz_rmb = -1;
5892           break;
5893         }
5894 
5895         cz_rmb = -1;
5896         break;
5897       }
5898 
5899       if( ( curtune ) && ( curtune->at_curpanel == PN_TRACKER ) )
5900       {
5901         if( ( x >= INSLIST_X ) && ( x < (INSLIST_X+INSLIST_W) ) &&
5902             ( y >= INSLIST_Y ) && ( y < (INSLIST_Y+INSLIST_H) ) )
5903         {
5904           int32 i, j;
5905 
5906           i = (y-(INSLIST_Y+5))/14;
5907           if( i < 0 ) i = 0;
5908           j = i+curtune->at_topins;
5909 
5910           tbx[TB_INSNAME2].content  = curtune->at_Instruments[j].ins_Name;
5911           tbx[TB_INSNAME2].y        = (INSLIST_Y+5)+(i*14)-1;
5912           tbx[TB_INSNAME2].flags   |= TBF_VISIBLE|TBF_ACTIVE;
5913           tbx[TB_INSNAME2].spos = 0;
5914           setbefore_string( curtune, tbx[TB_INSNAME2].content );
5915           etbx = &tbx[TB_INSNAME2];
5916           if( x < etbx->x ) x = etbx->x;
5917           etbx->cpos = ((x-etbx->x)>>3)+etbx->spos;
5918           gui_render_tbox( &mainbm, etbx );
5919         }
5920       }
5921 
5922       if( ( curtune ) && ( curtune->at_curpanel == PN_INSED ) )
5923       {
5924         if( ( x >= INSLSTB_X ) && ( x < (INSLSTB_X+INSLSTB_W) ) &&
5925             ( y >= INSLSTB_Y ) && ( y < (INSLSTB_Y+INSLSTB_H) ) )
5926         {
5927           int32 i, j;
5928           BOOL doit = TRUE;
5929 
5930           i = (y-INSLSTB_Y)>>4;
5931           i += curtune->at_topinsb;
5932           if( i < 1 ) i = 1;
5933           if( i > 63 ) i = 63;
5934           j = curtune->at_curins;
5935 
5936           if( qual & IEQUALIFIER_CONTROL )
5937           {
5938             rp_clear_instrument( &curtune->at_Instruments[i] );
5939             curtune->at_curins = i;
5940           } else {
5941             if( i == j ) break;
5942 
5943             curtune->at_curins = i;
5944             if( curtune->at_Instruments[i].ins_PList.pls_Length != 0 )
5945             {
5946               gui_render_inslistb( TRUE );
5947               doit = gui_req( REQIMAGE_QUESTION, "Copy Instrument", "That instrument is not empty.\nDo you want to copy over it?", "_Yes yes!|Whoooooooops! _No!!!" );
5948             }
5949 
5950             if( doit )
5951               curtune->at_Instruments[i] = curtune->at_Instruments[j];
5952           }
5953 
5954           if( doit )
5955           {
5956             gui_render_tunepanel( TRUE );
5957             curtune->at_modified = TRUE;
5958           }
5959         }
5960       }
5961 
5962       break;
5963   }
5964 }
5965 
gui_posed_moveright(void)5966 void gui_posed_moveright( void )
5967 {
5968   curtune->at_posed_curs++;
5969 
5970   if( (curtune->at_posed_curs/5+curtune->at_curlch) >= curtune->at_Channels )
5971   {
5972     curtune->at_posed_curs = 0;
5973     curtune->at_curlch = 0;
5974   }
5975 
5976   while( (curtune->at_posed_curs/5) > 5 )
5977   {
5978     curtune->at_curlch++;
5979     curtune->at_posed_curs -= 5;
5980   }
5981 }
5982 
gui_textbox_keypress(struct rawbm * bm,struct textbox ** ttbx,struct IntuiMessage * msg)5983 void gui_textbox_keypress( struct rawbm *bm, struct textbox **ttbx, struct IntuiMessage *msg )
5984 {
5985   int32 i, j, actual;
5986   TEXT kbuf[80];
5987   int32 lqual;
5988 
5989   if( *ttbx == NULL ) return;
5990 
5991   lqual = msg->Qualifier;
5992 
5993   switch( msg->Code )
5994   {
5995     case 79:  // Left arrow
5996       if( lqual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
5997         (*ttbx)->cpos = 0;
5998       else
5999         if( (*ttbx)->cpos > 0 ) (*ttbx)->cpos--;
6000       gui_render_tbox( bm, *ttbx );
6001       break;
6002     case 78:  // Right arrow
6003       if( lqual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
6004         (*ttbx)->cpos = strlen( (*ttbx)->content );
6005       else
6006         (*ttbx)->cpos++;
6007       gui_render_tbox( bm, *ttbx );
6008       break;
6009     case 65:  // Backspace
6010       if( (*ttbx)->cpos == 0 ) break;
6011 
6012       j = strlen( (*ttbx)->content );
6013 
6014       if( lqual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
6015       {
6016         for( i=(*ttbx)->cpos; i<=j; i++ ) (*ttbx)->content[i-(*ttbx)->cpos] = (*ttbx)->content[i];
6017         (*ttbx)->cpos = 0;
6018         gui_render_tbox( bm, *ttbx );
6019         break;
6020       }
6021 
6022       for( i=(*ttbx)->cpos-1; i<j; i++ ) (*ttbx)->content[i] = (*ttbx)->content[i+1];
6023       (*ttbx)->cpos--;
6024       gui_render_tbox( bm, *ttbx );
6025       break;
6026     case 70:  // Del
6027       if( lqual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
6028       {
6029         (*ttbx)->content[(*ttbx)->cpos] = 0;
6030         gui_render_tbox( bm, *ttbx );
6031         break;
6032       }
6033 
6034       if( (*ttbx)->cpos >= strlen( (*ttbx)->content ) ) break;
6035       j = strlen( (*ttbx)->content );
6036       for( i=(*ttbx)->cpos; i<j; i++ ) (*ttbx)->content[i] = (*ttbx)->content[i+1];
6037       gui_render_tbox( bm, *ttbx );
6038       break;
6039     case 68:  // Enter
6040     case 197:  // ESC
6041       (*ttbx)->flags &= ~TBF_ACTIVE;
6042       gui_render_tbox( bm, *ttbx );
6043       if( bm == &mainbm )
6044         gui_tbox_finish_editing();
6045       else
6046         gui_ptbox_finish_editing();
6047       break;
6048     default:
6049 #ifndef __SDL_WRAPPER__
6050       iev.ie_Code         = msg->Code;
6051       iev.ie_Qualifier    = msg->Qualifier;
6052       /* recover dead key codes & qualifiers */
6053       iev.ie_EventAddress = (APTR *) *((ULONG *)msg->IAddress);
6054 
6055       actual = (IKeymap->MapRawKey( &iev, kbuf, 80, 0 ) == 1);
6056 #else
6057       actual = (((event.key.keysym.unicode&0xff)!=0) && ((event.key.keysym.unicode&0xff00)==0));
6058       kbuf[0] = event.key.keysym.unicode;
6059 #endif
6060       if( ( actual ) && ( kbuf[0] > 31 ) && ( kbuf[0] < 128 ) )
6061       {
6062         if( strlen( (*ttbx)->content ) >= (*ttbx)->maxlen ) break;
6063 
6064         j = strlen( (*ttbx)->content );
6065         for( i=j+1; i>(*ttbx)->cpos; i-- ) (*ttbx)->content[i] = (*ttbx)->content[i-1];
6066         (*ttbx)->content[(*ttbx)->cpos] = kbuf[0];
6067         (*ttbx)->cpos++;
6068         gui_render_tbox( bm, *ttbx );
6069 //      } else {
6070 //        if( msg->Code < 128 )
6071 //          printf( "%d (%d)\n", msg->Code, msg->Code+128 );
6072       }
6073       break;
6074   }
6075 }
6076 
gui_whichpop(int16 x,int16 y)6077 int32 gui_whichpop( int16 x, int16 y )
6078 {
6079   int i;
6080 
6081   for( i=0; i<PP_END; i++ )
6082   {
6083     if( ( x >= pp[i].x ) && ( x < pp[i].x+20 ) &&
6084         ( y >= pp[i].y ) && ( y < pp[i].y+18 ) )
6085       return i;
6086   }
6087 
6088   return -1;
6089 }
6090 
gui_checkpop_down(int16 x,int16 y)6091 BOOL gui_checkpop_down( int16 x, int16 y )
6092 {
6093   whichpop = gui_whichpop( x, y );
6094   if( whichpop == -1 ) return FALSE;
6095 
6096   gui_render_popup( whichpop, TRUE );
6097 #ifdef __SDL_WRAPPER__
6098   bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6099 #endif
6100   return TRUE;
6101 }
6102 
gui_checkpop_up(int16 x,int16 y)6103 BOOL gui_checkpop_up( int16 x, int16 y )
6104 {
6105   uint32 ok;
6106 
6107   if( whichpop != -1 )
6108   {
6109     if( gui_whichpop( x, y ) == whichpop )
6110     {
6111       switch( whichpop )
6112       {
6113         case PP_SONGDIR:
6114 #ifndef __SDL_WRAPPER__
6115           ok = IAsl->AslRequestTags( dir_req,
6116             ASLFR_Window,        mainwin,
6117             ASLFR_SleepWindow,   TRUE,
6118             ASLFR_InitialDrawer, songdir,
6119             ASLFR_TitleText,     "Select default song directory",
6120             TAG_DONE );
6121           if( !ok ) break;
6122 
6123           strncpy( songdir, dir_req->fr_Drawer, 512 );
6124 #else
6125           if (directoryrequester("Select default song directory", songdir))
6126             strncpy(remsongdir, songdir, 512);
6127 #endif
6128           gui_render_tbox( &prefbm, &ptb[PTB_SONGDIR] );
6129           break;
6130 
6131         case PP_INSTDIR:
6132 #ifndef __SDL_WRAPPER__
6133           ok = IAsl->AslRequestTags( dir_req,
6134             ASLFR_Window,        mainwin,
6135             ASLFR_SleepWindow,   TRUE,
6136             ASLFR_InitialDrawer, instdir,
6137             ASLFR_TitleText,     "Select default instrument directory",
6138             TAG_DONE );
6139           if( !ok ) break;
6140 
6141           strncpy( instdir, dir_req->fr_Drawer, 512 );
6142 #else
6143           if (directoryrequester("Select default instrument directory", instdir))
6144             strncpy(reminstdir, instdir, 512);
6145 #endif
6146           gui_render_tbox( &prefbm, &ptb[PTB_INSTDIR] );
6147           break;
6148 
6149         case PP_SKINDIR:
6150 #ifndef __SDL_WRAPPER__
6151           ok = IAsl->AslRequestTags( dir_req,
6152             ASLFR_Window,        mainwin,
6153             ASLFR_SleepWindow,   TRUE,
6154             ASLFR_InitialDrawer, skindir,
6155             ASLFR_TitleText,     "Select skin directory",
6156             TAG_DONE );
6157           if( !ok ) break;
6158 
6159           strncpy( skindir, dir_req->fr_Drawer, 512 );
6160 #else
6161 #ifdef __APPLE__
6162           osxGetResourcesPath(skindir, "Skins");
6163           directoryrequester("Select skin directory", skindir);
6164           // Convert absolute path to relative path for bundle resources
6165           char *resPath = osxGetResourcesPath(NULL, "");
6166           if(strncmp(resPath, skindir, strlen(resPath)) == 0)
6167             strcpy(skindir, skindir + strlen(resPath) + 1);
6168 #else
6169           directoryrequester("Select skin directory", skindir);
6170 #endif
6171 #endif
6172           gui_render_tbox( &prefbm, &ptb[PTB_SKINDIR] );
6173           break;
6174       }
6175     }
6176 
6177     gui_render_popup( whichpop, FALSE );
6178     whichpop = -1;
6179   }
6180 
6181 #ifdef __SDL_WRAPPER__
6182   bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6183 #endif
6184   return gui_whichpop( x, y ) != -1;
6185 }
6186 
gui_whichpc(int16 x,int16 y)6187 int32 gui_whichpc( int16 x, int16 y )
6188 {
6189   int i;
6190 
6191   for( i=0; i<PC_END; i++ )
6192   {
6193 #if defined(WIN32) || defined(__APPLE__)
6194     if( i == 0 ) continue;
6195 #endif
6196     if( ( x >= pcyc[i].x ) && ( x < pcyc[i].x+160 ) &&
6197         ( y >= pcyc[i].y ) && ( y < pcyc[i].y+24 ) )
6198       return i;
6199   }
6200 
6201   return -1;
6202 }
6203 
gui_checkpc_down(int16 x,int16 y)6204 BOOL gui_checkpc_down( int16 x, int16 y )
6205 {
6206   whichcyc = gui_whichpc( x, y );
6207   if( whichcyc == -1 ) return FALSE;
6208 
6209   gui_render_pcycle( whichcyc, TRUE );
6210 #ifdef __SDL_WRAPPER__
6211   bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6212 #endif
6213   return TRUE;
6214 }
6215 
gui_checkpc_up(int16 x,int16 y)6216 BOOL gui_checkpc_up( int16 x, int16 y )
6217 {
6218   if( whichcyc != -1 )
6219   {
6220     if( gui_whichpc( x, y ) == whichcyc )
6221     {
6222       pcyc[whichcyc].copt = (pcyc[whichcyc].copt+1)%pcyc[whichcyc].numopts;
6223 
6224       switch( whichcyc )
6225       {
6226         case PC_WMODE:
6227           pref_fullscr = (pcyc[PC_WMODE].copt == 1);
6228           break;
6229 
6230         case PC_DEFSTEREO:
6231           pref_defstereo = pcyc[PC_DEFSTEREO].copt;
6232           break;
6233 
6234         case PC_BLANKZERO:
6235           pref_blankzeros = (pcyc[PC_BLANKZERO].copt == 1);
6236           if( curtune ) gui_render_tracked( TRUE );
6237           break;
6238 
6239         case PC_MAXUNDOBUF:
6240           pref_maxundobuf = pcyc[PC_MAXUNDOBUF].copt;
6241           break;
6242       }
6243     }
6244 
6245     gui_render_pcycle( whichcyc, FALSE );
6246 #ifdef __SDL_WRAPPER__
6247     bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6248 #endif
6249   }
6250   return gui_whichpc( x, y ) != -1;
6251 }
6252 
gui_findlastpos(struct ahx_tune * at)6253 int32 gui_findlastpos( struct ahx_tune *at )
6254 {
6255   int32 maxpos, i;
6256 
6257   for( maxpos=999; maxpos>0; maxpos-- )
6258   {
6259     for( i=0; i<MAX_CHANNELS; i++ )
6260       if( ( at->at_Positions[maxpos].pos_Track[i] != 0 ) ||
6261           ( at->at_Positions[maxpos].pos_Transpose[i] != 0 ) )
6262         return maxpos;
6263   }
6264 
6265   return 0;
6266 }
6267 
gui_render_everything(void)6268 void gui_render_everything( void )
6269 {
6270   // Do the logo
6271   put_bitmap( BM_LOGO, 0, 0, 256, 96 );
6272   put_bitmap( BM_DEPTH, 776, 0, 24, 24 );
6273   put_bitmap( BM_BLANK, 776, 24, 24, 72 );
6274   gui_render_main_buttonbank();
6275   gui_render_tunepanel( TRUE );
6276   gui_render_wavemeter();
6277 #ifdef __SDL_WRAPPER__
6278   if (prefwin_open) gui_render_prefs();
6279 #endif
6280 }
6281 
gui_restart(void)6282 BOOL gui_restart( void )
6283 {
6284 #ifndef __SDL_WRAPPER__
6285   int32 i;
6286   BOOL oh_crap = FALSE;
6287 
6288   // Shutdown just the things we have to shut in order to reopen
6289   // with new settings
6290   gui_close_prefs();
6291   about_close();
6292 
6293   IIntuition->CloseWindow( mainwin );
6294   mainwin = NULL;
6295   gui_sigs &= ~mainwin_sig;
6296   mainwin_sig = 0;
6297 
6298   if( scr ) IIntuition->CloseScreen( scr );
6299   scr = NULL;
6300 
6301   for( i=0; i<BM_END; i++ ) { IGraphics->FreeBitMap( bitmaps[i].bm ); bitmaps[i].bm = NULL; }
6302   for( i=0; i<TB_END; i++ ) { IGraphics->FreeBitMap( tbx[i].bm.bm ); tbx[i].bm.bm = NULL; }
6303 
6304   IGraphics->CloseFont( prpfont ); prpfont = NULL;
6305   IGraphics->CloseFont( fixfont ); fixfont = NULL;
6306   IGraphics->CloseFont( sfxfont ); sfxfont = NULL;
6307 
6308   // Set some defaults
6309   strcpy( fixfontname, "Bitstream Vera Sans Mono.font" );
6310   strcpy( sfxfontname, "Bitstream Vera Sans Mono.font" );
6311   strcpy( prpfontname, "Bitstream Vera Sans.font" );
6312   strcpy( skinext,     ".png" );
6313 
6314   numzones = 0;
6315   numpzones = 0;
6316 
6317   if (!oh_crap)
6318   {
6319     if (!gui_open())
6320     {
6321       oh_crap = TRUE;
6322     }
6323   }
6324 
6325   if( oh_crap )
6326   {
6327     BPTR cdir, lock;
6328     int32 i;
6329     struct ahx_tune *at;
6330     char rname[64];
6331 
6332     gui_req( REQIMAGE_ERROR, "Oh crap!", "There was an error re-opening the GUI,\nand Hively has to quit. All open songs\nwill be saved to 'Songs/Rescue'", "OK" );
6333 
6334     lock = IDOS->Lock( "Songs/Rescue", ACCESS_READ );
6335     if( !lock )
6336     {
6337       lock = IDOS->CreateDirTree( "Songs/Rescue" );
6338       if( !lock )
6339       {
6340         lock = IDOS->Lock( "", ACCESS_READ );
6341         if( !lock )
6342         {
6343           // Oh fuck.
6344           return FALSE;
6345         }
6346       }
6347     }
6348     cdir = IDOS->CurrentDir( lock );
6349 
6350     IExec->ObtainSemaphore( rp_list_ss );
6351 
6352     i=1;
6353     at = (struct ahx_tune *)IExec->GetHead(rp_tunelist);
6354     while( at )
6355     {
6356       sprintf( rname, "HVL.rescuetab%ld", i++ );
6357       rp_save_hvl( rname, at );
6358       at = (struct ahx_tune *)IExec->GetSucc(&at->at_ln);
6359     }
6360 
6361     IDOS->CurrentDir( cdir );
6362     IDOS->UnLock( lock );
6363     IExec->ReleaseSemaphore( rp_list_ss );
6364     return FALSE;
6365   }
6366 #else
6367   // Just reload the skin...
6368   SDL_FreeSurface(bitmaps[BM_LOGO].srf );       bitmaps[BM_LOGO].srf = NULL;
6369   SDL_FreeSurface(bitmaps[BM_TAB_AREA].srf );   bitmaps[BM_TAB_AREA].srf = NULL;
6370   SDL_FreeSurface(bitmaps[BM_TAB_LEFT].srf );   bitmaps[BM_TAB_LEFT].srf = NULL;
6371   SDL_FreeSurface(bitmaps[BM_TAB_MID] .srf) ;   bitmaps[BM_TAB_MID] .srf = NULL;
6372   SDL_FreeSurface(bitmaps[BM_TAB_RIGHT].srf );  bitmaps[BM_TAB_RIGHT].srf = NULL;
6373   SDL_FreeSurface(bitmaps[BM_ITAB_LEFT].srf );  bitmaps[BM_ITAB_LEFT].srf = NULL;
6374   SDL_FreeSurface(bitmaps[BM_ITAB_MID].srf );   bitmaps[BM_ITAB_MID].srf = NULL;
6375   SDL_FreeSurface(bitmaps[BM_ITAB_RIGHT].srf ); bitmaps[BM_ITAB_RIGHT].srf = NULL;
6376   SDL_FreeSurface(bitmaps[BM_BUTBANKR].srf );   bitmaps[BM_BUTBANKR].srf = NULL;
6377   SDL_FreeSurface(bitmaps[BM_BUTBANKP].srf );   bitmaps[BM_BUTBANKP].srf = NULL;
6378   SDL_FreeSurface(bitmaps[BM_BG_TRACKER].srf ); bitmaps[BM_BG_TRACKER].srf = NULL;
6379   SDL_FreeSurface(bitmaps[BM_BG_INSED].srf );   bitmaps[BM_BG_INSED].srf = NULL;
6380   SDL_FreeSurface(bitmaps[BM_PLUSMINUS].srf );  bitmaps[BM_PLUSMINUS].srf = NULL;
6381   SDL_FreeSurface(bitmaps[BM_VUMETER] .srf) ;   bitmaps[BM_VUMETER] .srf = NULL;
6382   SDL_FreeSurface(bitmaps[BM_DEPTH].srf ) ;     bitmaps[BM_DEPTH].srf = NULL;
6383   SDL_FreeSurface(bitmaps[BM_BLANK].srf ) ;     bitmaps[BM_BLANK].srf = NULL;
6384   SDL_FreeSurface(bitmaps[BM_WAVEMETERS].srf ); bitmaps[BM_WAVEMETERS].srf = NULL;
6385   SDL_FreeSurface(bitmaps[BM_PRF_BG].srf );     bitmaps[BM_PRF_BG].srf = NULL;
6386   SDL_FreeSurface(bitmaps[BM_PRF_CYCLE].srf );  bitmaps[BM_PRF_CYCLE].srf = NULL;
6387   SDL_FreeSurface(bitmaps[BM_TRKBANKR].srf );   bitmaps[BM_TRKBANKR].srf = NULL;
6388   SDL_FreeSurface(bitmaps[BM_TRKBANKP].srf );   bitmaps[BM_TRKBANKP].srf = NULL;
6389   SDL_FreeSurface(bitmaps[BM_CHANMUTE].srf );   bitmaps[BM_CHANMUTE].srf = NULL;
6390   SDL_FreeSurface(bitmaps[BM_DIRPOPUP].srf );   bitmaps[BM_DIRPOPUP].srf = NULL;
6391 
6392   if (bitmaps[BM_ITAB_TEXT].srf)
6393   {
6394     SDL_FreeSurface(bitmaps[BM_ITAB_TEXT].srf );
6395     bitmaps[BM_ITAB_TEXT].srf = NULL;
6396   }
6397 
6398   if (bitmaps[BM_TAB_TEXT].srf)
6399   {
6400     SDL_FreeSurface(bitmaps[BM_TAB_TEXT].srf );
6401     bitmaps[BM_TAB_TEXT].srf = NULL;
6402   }
6403 
6404   if( !gui_open_skin_images() )
6405   {
6406     printf( "Error loading skin. Reverting to SIDMonster-Light...\n" );
6407     strcpy( skindir, "Skins/SIDMonster-Light" );
6408     if( !gui_open_skin_images() ) return FALSE;
6409   }
6410 
6411   gui_render_everything();
6412 #endif
6413   return TRUE;
6414 }
6415 
6416 #ifdef __SDL_WRAPPER__
translate_sdl_event(void)6417 struct IntuiMessage *translate_sdl_event(void)
6418 {
6419   static uint32 mkqual = 0;
6420   static struct IntuiMessage fakemsg;
6421 
6422   fakemsg.IAddress  = NULL;
6423 
6424   switch (event.type)
6425   {
6426     case SDL_MOUSEMOTION:
6427       fakemsg.Class     = IDCMP_MOUSEMOVE;
6428       fakemsg.Qualifier = mkqual;
6429       fakemsg.Code      = 0;
6430       fakemsg.MouseX    = event.motion.x;
6431       fakemsg.MouseY    = event.motion.y;
6432       break;
6433 
6434     case SDL_MOUSEBUTTONDOWN:
6435     {
6436       static struct IntuiWheelData iwd;
6437 
6438       if (event.button.button == SDL_BUTTON_WHEELUP)
6439       {
6440         fakemsg.Class    = IDCMP_EXTENDEDMOUSE;
6441         fakemsg.Code     = IMSGCODE_INTUIWHEELDATA;
6442         fakemsg.IAddress = &iwd;
6443         fakemsg.MouseX    = event.motion.x;
6444         fakemsg.MouseY    = event.motion.y;
6445         iwd.WheelY    = -1;
6446         break;
6447       }
6448 
6449       if (event.button.button == SDL_BUTTON_WHEELDOWN)
6450       {
6451         fakemsg.Class    = IDCMP_EXTENDEDMOUSE;
6452         fakemsg.Code     = IMSGCODE_INTUIWHEELDATA;
6453         fakemsg.IAddress = &iwd;
6454         fakemsg.MouseX   = event.motion.x;
6455         fakemsg.MouseY   = event.motion.y;
6456         iwd.WheelY    = 1;
6457         break;
6458       }
6459 
6460       if (event.button.button == SDL_BUTTON_RIGHT) mkqual |= IEQUALIFIER_RBUTTON;
6461       fakemsg.Class     = IDCMP_MOUSEBUTTONS;
6462       fakemsg.Code      = event.button.button;
6463       fakemsg.Qualifier = mkqual;
6464       fakemsg.MouseX    = event.motion.x;
6465       fakemsg.MouseY    = event.motion.y;
6466       break;
6467     }
6468 
6469     case SDL_MOUSEBUTTONUP:
6470       if (event.button.button == SDL_BUTTON_RIGHT) mkqual &= ~IEQUALIFIER_RBUTTON;
6471       fakemsg.Class     = IDCMP_MOUSEBUTTONS;
6472       fakemsg.Code      = event.button.button | 0x100;
6473       fakemsg.Qualifier = mkqual;
6474       fakemsg.MouseX    = event.motion.x;
6475       fakemsg.MouseY    = event.motion.y;
6476       break;
6477 
6478     case SDL_KEYDOWN:
6479       switch (event.key.keysym.sym)
6480       {
6481         case SDLK_LSHIFT: mkqual |= IEQUALIFIER_LSHIFT; break;
6482         case SDLK_RSHIFT: mkqual |= IEQUALIFIER_RSHIFT; break;
6483         case SDLK_LCTRL:  mkqual |= IEQUALIFIER_CONTROL; break;
6484         case SDLK_RCTRL:  if (!pref_rctrlplaypos) { mkqual |= IEQUALIFIER_CONTROL; } break;
6485         case SDLK_LALT:   mkqual |= IEQUALIFIER_LALT; break;
6486         case SDLK_LSUPER: mkqual |= IEQUALIFIER_LCOMMAND; break;
6487 #ifdef __WIN32__
6488         /* Workaround: On Windows, SDLK_RALT is always prefixed by SDLK_RCTRL */
6489         /* but we want RALT to be treated separately, and since RCTRL+RALT    */
6490         /* isn't a key combo we care about, we make pressing RALT cancel out  */
6491         /* the dummy RCTRL press. */
6492         case SDLK_RALT:   mkqual &= ~IEQUALIFIER_CONTROL; break;
6493 #endif
6494       }
6495 
6496       fakemsg.Class     = IDCMP_RAWKEY;
6497       fakemsg.Code      = sdl_keysym_to_amiga_rawkey(event.key.keysym.sym);
6498       fakemsg.Qualifier = mkqual;
6499       break;
6500 
6501     case SDL_KEYUP:
6502       switch (event.key.keysym.sym)
6503       {
6504         case SDLK_LSHIFT: mkqual &= ~IEQUALIFIER_LSHIFT; break;
6505         case SDLK_RSHIFT: mkqual &= ~IEQUALIFIER_RSHIFT; break;
6506         case SDLK_LCTRL:  mkqual &= ~IEQUALIFIER_CONTROL; break;
6507         case SDLK_RCTRL:  if (!pref_rctrlplaypos) { mkqual &= ~IEQUALIFIER_CONTROL; } break;
6508         case SDLK_LALT:   mkqual &= ~IEQUALIFIER_LALT; break;
6509         case SDLK_LSUPER: mkqual &= ~IEQUALIFIER_LCOMMAND; break;
6510       }
6511 
6512       fakemsg.Class     = IDCMP_RAWKEY;
6513       fakemsg.Code      = sdl_keysym_to_amiga_rawkey(event.key.keysym.sym) | 0x80;
6514       fakemsg.Qualifier = mkqual;
6515       break;
6516   }
6517 
6518   return &fakemsg;
6519 }
6520 #endif
6521 
gui_handler(uint32 gotsigs)6522 void gui_handler( uint32 gotsigs )
6523 {
6524   struct IntuiMessage *msg;
6525 
6526   const int8 hexkeys[] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 53, 51, 34, 18, 35 };
6527 
6528   const int8 inskeys[] = { 15, 29, 30, 31, 45, 46, 47, 61, 62, 63 };
6529 
6530   const int8 pianokeys[] = { 49, 33, 50, 34, 51, 52, 36, 53, 37, 54, 38, 55,
6531                        16,  2, 17,  3, 18, 19,  5, 20,  6, 21,  7, 22,
6532                        23,  9, 24, 10, 25 };
6533 
6534   const int8 extrakeys[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
6535                        56, 40, 57, 41, 58, -1, -1, -1, -1, -1, -1, -1,
6536                        -1, -1, -1, -1, -1 };
6537 
6538   struct ahx_step *stp, *pstp;
6539 
6540 #ifndef __SDL_WRAPPER__
6541   if( gotsigs & gui_tick_sig )
6542 #else
6543   if( event.type == SDL_USEREVENT )
6544 #endif
6545   {
6546     if( curtune == rp_curtune )
6547     {
6548       gui_render_tunepanel( FALSE );
6549       gui_render_vumeters();
6550     }
6551     if( (wm_count++)&1 )
6552       gui_render_wavemeter();
6553 
6554 #ifdef __SDL_WRAPPER__
6555     if (prefwin_open)
6556       bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6557     return;
6558 #endif
6559   }
6560 
6561 #ifndef __SDL_WRAPPER__
6562   if( gotsigs & prefwin_sig )
6563 #else
6564   if( prefwin_open )
6565 #endif
6566   {
6567     BOOL wantclose;
6568     int16 x, y;
6569 
6570     wantclose = FALSE;
6571 #ifndef __SDL_WRAPPER__
6572     while( ( msg = (struct IntuiMessage *)IExec->GetMsg( prefwin->UserPort ) ) )
6573 #else
6574     msg = translate_sdl_event();
6575 #endif
6576     {
6577       switch( msg->Class )
6578       {
6579         case IDCMP_RAWKEY:
6580           // In a textbox?
6581           if( ptbx != NULL )
6582           {
6583             gui_textbox_keypress( &prefbm, &ptbx, msg );
6584 #ifdef __SDL_WRAPPER__
6585             bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6586 #endif
6587             break;
6588           }
6589 
6590           switch( msg->Code )
6591           {
6592             case 197:
6593             case 13: // ESC is intermittently broken on my laptop :-/
6594               wantclose = TRUE;
6595               break;
6596           }
6597           break;
6598         case IDCMP_MOUSEBUTTONS:
6599 #ifndef __SDL_WRAPPER__
6600           x = msg->MouseX-pw_bl;
6601           y = msg->MouseY-pw_bt;
6602 #else
6603           x = msg->MouseX-200;
6604           y = msg->MouseY-150;
6605 #endif
6606 
6607           switch( msg->Code )
6608           {
6609             case SELECTDOWN:
6610               if( gui_check_ptbox_press( x, y ) ) return;
6611 
6612               if( ptbx )
6613               {
6614                 ptbx->flags &= ~TBF_ACTIVE;
6615                 gui_render_tbox( &prefbm, ptbx );
6616                 gui_ptbox_finish_editing();
6617 #ifdef __SDL_WRAPPER__
6618                 bm_to_bm(&prefbm, -4, -4, &mainbm, 196, 146, 408, 308);
6619 #endif
6620               }
6621 
6622               if( gui_checkpc_down( x, y ) ) break;
6623               if( gui_checkpop_down( x, y ) ) break;
6624               break;
6625             case SELECTUP:
6626               if( ptbx != NULL ) break;
6627 
6628               if( gui_checkpc_up( x, y ) ) break;
6629               if( gui_checkpop_up( x, y ) ) break;
6630               break;
6631           }
6632           break;
6633 
6634 #ifndef __SDL_WRAPPER__
6635         case IDCMP_CLOSEWINDOW:
6636           wantclose = TRUE;
6637 #endif
6638           break;
6639       }
6640 #ifndef __SDL_WRAPPER__
6641       IExec->ReplyMsg( (struct Message *)msg );
6642 #endif
6643     }
6644 
6645     if( wantclose ) gui_close_prefs();
6646 #ifdef __SDL_WRAPPER__
6647     return;
6648 #endif
6649   }
6650 
6651 #ifndef __SDL_WRAPPER__
6652   if( gotsigs & mainwin_sig )
6653 #endif
6654   {
6655     int32 panel, maxpos;
6656     struct ahx_plsentry *cple;
6657     struct ahx_instrument *cins;
6658     BOOL cutting;
6659     int16 next;
6660 #ifndef __SDL_WRAPPER__
6661     while( ( msg = (struct IntuiMessage *)IExec->GetMsg( mainwin->UserPort ) ) )
6662 #else
6663     msg = translate_sdl_event();
6664 #endif
6665 
6666     {
6667       BOOL donkey;
6668       int32 i, j, k, l, chan, track, tran;
6669       struct IntuiWheelData *iwd;
6670 
6671       switch( msg->Class )
6672       {
6673         case IDCMP_EXTENDEDMOUSE:
6674           switch( msg->Code )
6675           {
6676             case IMSGCODE_INTUIWHEELDATA:
6677               iwd = (struct IntuiWheelData *)msg->IAddress;
6678               gui_wheelybin( msg->MouseX, msg->MouseY, iwd->WheelY );
6679               break;
6680           }
6681           break;
6682         case IDCMP_RAWKEY:
6683           qual   = msg->Qualifier;
6684           donkey = FALSE;
6685 
6686           // In a textbox?
6687           if( etbx != NULL )
6688           {
6689             gui_textbox_keypress( &mainbm, &etbx, msg );
6690             break;
6691           }
6692 
6693           // Keys for any mode
6694           switch( qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT|IEQUALIFIER_CONTROL|IEQUALIFIER_LALT|IEQUALIFIER_LCOMMAND) )
6695           {
6696             case 0:
6697               // No qualifiers
6698               switch( msg->Code )
6699               {
6700                 case 13: // \ = drum pad mode
6701                   if( curtune->at_drumpadmode )
6702                     curtune->at_drumpadmode = FALSE;
6703                   else
6704                     curtune->at_drumpadmode = TRUE;
6705                   gui_set_various_things( curtune );
6706                   donkey = TRUE;
6707                   break;
6708                 case 48: // Blank next to Z (shut up)
6709                   rp_stop();
6710                   gui_render_wavemeter();
6711                   gui_render_tracked( TRUE );  // Kill the VUMeters
6712                   curtune->at_doing = D_IDLE;
6713                   donkey = TRUE;
6714                   break;
6715 
6716                 case 11: // Minus
6717                   posedadvance = !posedadvance;
6718                   donkey = TRUE;
6719                   break;
6720 
6721                 case 12: // Equals
6722                   if( !curtune ) break;
6723                   if( curtune->at_doing == D_PLAYING ) break;
6724 
6725                   rp_play_row( curtune );
6726                   donkey = TRUE;
6727                   break;
6728 
6729                 case 80: // F1
6730                 case 81: // F2
6731                 case 82: // F3
6732                 case 83: // F4
6733                 case 84: // F5
6734                   donkey = TRUE;
6735                   basekey = (msg->Code-80)*12;
6736                   break;
6737                 case 197:
6738                   donkey = TRUE;
6739 
6740                   if( !curtune ) break;
6741 
6742                   if( curtune->at_curpanel == PN_INSED )
6743                     curtune->at_curpanel = PN_TRACKER;
6744                   else
6745                     curtune->at_curpanel = PN_INSED;
6746                   gui_render_tunepanel( TRUE );
6747                   break;
6748                 case 103:
6749                   donkey = TRUE;
6750                   curtune->at_doing = D_IDLE;
6751                   if( rp_play_pos( curtune, FALSE ) )
6752                     curtune->at_doing = D_PLAYING;
6753                   break;
6754                 case 101:
6755                   donkey = TRUE;
6756                   curtune->at_doing = D_IDLE;
6757                   if( rp_play_song( curtune, curtune->at_curss, FALSE ) )
6758                     curtune->at_doing = D_PLAYING;
6759                   break;
6760                 case 94:
6761                   donkey = TRUE;
6762                   if( curtune == NULL ) break;
6763                   curtune->at_baseins += 10;
6764                   if( curtune->at_baseins > 60 ) curtune->at_baseins = 60;
6765                   break;
6766                 case 74:
6767                   donkey = TRUE;
6768                   if( curtune == NULL ) break;
6769                   curtune->at_baseins -= 10;
6770                   if( curtune->at_baseins < 0 ) curtune->at_baseins = 0;
6771                   break;
6772               }
6773               break;
6774 
6775             case IEQUALIFIER_LSHIFT:  // Shifty
6776             case IEQUALIFIER_RSHIFT:  // Shifty
6777             case IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT: // Shifty shift
6778 
6779               chan = track = -1;
6780               if( curtune )
6781               {
6782                 chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
6783                 track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
6784               }
6785 
6786               cutting = FALSE;
6787 
6788               switch( msg->Code )
6789               {
6790                 case 79:  // Shift+Left (pos up)
6791                   donkey = TRUE;
6792                   if( !curtune ) break;
6793                   if( curtune->at_PosNr == 0 ) break;
6794                   curtune->at_PosNr--;
6795                   gui_render_posed( TRUE );
6796                   gui_render_tracked( TRUE );
6797                   break;
6798 
6799                 case 78:  // Shift+Right (pos down)
6800                   donkey = TRUE;
6801                   if( !curtune ) break;
6802                   if( curtune->at_PosNr == 999 ) break;
6803                   curtune->at_PosNr++;
6804                   gui_render_posed( TRUE );
6805                   gui_render_tracked( TRUE );
6806                   break;
6807 
6808                 case 82:  // Shift+F3 (cut track to buffer)
6809                   cutting = TRUE;
6810                 case 83:  // Shift+F4 (copy track to buffer)
6811                   donkey = TRUE;
6812                   if( track == -1 ) break;
6813                   if( curtune->at_curpanel != PN_TRACKER ) break;
6814                   gui_copyregion( track, 0, curtune->at_TrackLength-1, CBF_NOTES|CBF_CMD1|CBF_CMD2, cutting );
6815                   gui_render_tracked( TRUE );
6816                   break;
6817                 case 84:  // Shift+F5 (paste)
6818                   donkey = TRUE;
6819                   if( track == -1 ) break;
6820                   if( curtune->at_curpanel != PN_TRACKER ) break;
6821                   setbefore_track( curtune, track );
6822                   gui_paste( curtune, track, CBF_NOTES|CBF_CMD1|CBF_CMD2 );
6823                   setafter_track( curtune, track );
6824                   gui_render_tracked( TRUE );
6825                   break;
6826                 case 85:  // Shift+F6 (remember pos 0)
6827                 case 86:  // Shift+F7 (remember pos 1)
6828                 case 87:  // Shift+F8 (remember pos 2)
6829                 case 88:  // Shift+F9 (remember pos 3)
6830                 case 89:  // Shift+F10 (remember pos 4)
6831                   donkey = TRUE;
6832                   if( curtune == NULL ) break;
6833                   curtune->at_rempos[msg->Code-85] = curtune->at_NoteNr;
6834                   gui_render_tracked( TRUE );
6835                   break;
6836                 case 65:  // Shift+Backspace (delete row above)
6837                   donkey = TRUE;
6838                   if( curtune == NULL ) break;
6839 
6840                   switch( curtune->at_curpanel )
6841                   {
6842                     case PN_INSED:
6843                       if( curtune->at_idoing != D_EDITING ) break;
6844 
6845                       cins = &curtune->at_Instruments[curtune->at_curins];
6846                       cple = &cins->ins_PList.pls_Entries[255];
6847 
6848                       setbefore_plist( curtune, &cins->ins_PList.pls_Entries[0] );
6849 
6850                       if( cins->ins_pcury == 0 ) break;
6851 
6852                       cins->ins_pcury--;
6853                       for( i=cins->ins_pcury; i<254; i++ )
6854                         cins->ins_PList.pls_Entries[i] = cins->ins_PList.pls_Entries[i+1];
6855 
6856                       cple->ple_Note       = 0;
6857                       cple->ple_Fixed      = 0;
6858                       cple->ple_FX[0]      = 0;
6859                       cple->ple_FXParam[0] = 0;
6860                       cple->ple_FX[1]      = 0;
6861                       cple->ple_FXParam[1] = 0;
6862 
6863                       setafter_plist( curtune, &cins->ins_PList.pls_Entries[0] );
6864 
6865                       gui_render_perf( curtune, cins, TRUE );
6866                       break;
6867 
6868                     case PN_TRACKER:
6869                       switch( curtune->at_editing )
6870                       {
6871                         case E_TRACK:
6872                           if( curtune->at_doing != D_EDITING ) break;
6873 
6874                           chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
6875                           track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
6876 
6877                           if( curtune->at_NoteNr == 0 ) break;
6878 
6879                           setbefore_track( curtune, track );
6880 
6881                           curtune->at_NoteNr--;
6882 
6883                           for( i=curtune->at_NoteNr; i<(curtune->at_TrackLength-1); i++ )
6884                             curtune->at_Tracks[track][i] = curtune->at_Tracks[track][i+1];
6885 
6886                           curtune->at_Tracks[track][i].stp_Note       = 0;
6887                           curtune->at_Tracks[track][i].stp_Instrument = 0;
6888                           curtune->at_Tracks[track][i].stp_FX         = 0;
6889                           curtune->at_Tracks[track][i].stp_FXParam    = 0;
6890                           curtune->at_Tracks[track][i].stp_FXb        = 0;
6891                           curtune->at_Tracks[track][i].stp_FXbParam   = 0;
6892 
6893                           setafter_track( curtune, track );
6894 
6895                           gui_render_tracked( TRUE );
6896                           break;
6897 
6898                         case E_POS:
6899                           if( curtune->at_PosNr == 0 ) break;
6900 
6901                           curtune->at_PosNr--;
6902 
6903                           maxpos = gui_findlastpos( curtune )+1;
6904                           if( maxpos <= curtune->at_PosNr ) maxpos = curtune->at_PosNr+1;
6905 
6906                           setbefore_posregion( curtune, 0, curtune->at_PosNr, MAX_CHANNELS, maxpos-curtune->at_PosNr );
6907 
6908                           for( i=curtune->at_PosNr; i<999; i++ )
6909                             curtune->at_Positions[i] = curtune->at_Positions[i+1];
6910 
6911                           for( j=0; j<MAX_CHANNELS; j++ )
6912                           {
6913                             curtune->at_Positions[i].pos_Track[j]     = 0;
6914                             curtune->at_Positions[i].pos_Transpose[j] = 0;
6915                           }
6916 
6917                           setafter_posregion( curtune, 0, curtune->at_PosNr, MAX_CHANNELS, maxpos-curtune->at_PosNr );
6918 
6919                           gui_render_posed( TRUE );
6920                           break;
6921                       }
6922                       break;
6923                   }
6924                   break;
6925 
6926                 case 68:  // Shift+Enter (insert row)
6927                   donkey = TRUE;
6928                   if( curtune == NULL ) break;
6929 
6930                   switch( curtune->at_curpanel )
6931                   {
6932                     case PN_INSED:
6933                       if( curtune->at_idoing != D_EDITING ) break;
6934 
6935                       cins = &curtune->at_Instruments[curtune->at_curins];
6936                       cple = &cins->ins_PList.pls_Entries[cins->ins_pcury];
6937 
6938                       setbefore_plist( curtune, &cins->ins_PList.pls_Entries[0] );
6939 
6940                       for( i=255; i>cins->ins_pcury; i-- )
6941                         cins->ins_PList.pls_Entries[i] = cins->ins_PList.pls_Entries[i-1];
6942 
6943                       cple->ple_Note       = 0;
6944                       cple->ple_Fixed      = 0;
6945                       cple->ple_FX[0]      = 0;
6946                       cple->ple_FXParam[0] = 0;
6947                       cple->ple_FX[1]      = 0;
6948                       cple->ple_FXParam[1] = 0;
6949 
6950                       setafter_plist( curtune, &cins->ins_PList.pls_Entries[0] );
6951 
6952                       gui_render_perf( curtune, cins, TRUE );
6953                       break;
6954 
6955                     case PN_TRACKER:
6956                       switch( curtune->at_editing )
6957                       {
6958                         case E_TRACK:
6959                           if( curtune->at_doing != D_EDITING ) break;
6960 
6961                           chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
6962                           track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
6963 
6964                           setbefore_track( curtune, track );
6965 
6966                           for( i=(curtune->at_TrackLength-1); i>curtune->at_NoteNr; i-- )
6967                             curtune->at_Tracks[track][i] = curtune->at_Tracks[track][i-1];
6968 
6969                           curtune->at_Tracks[track][i].stp_Note       = 0;
6970                           curtune->at_Tracks[track][i].stp_Instrument = 0;
6971                           curtune->at_Tracks[track][i].stp_FX         = 0;
6972                           curtune->at_Tracks[track][i].stp_FXParam    = 0;
6973                           curtune->at_Tracks[track][i].stp_FXb        = 0;
6974                           curtune->at_Tracks[track][i].stp_FXbParam   = 0;
6975 
6976                           setafter_track( curtune, track );
6977 
6978                           gui_render_tracked( TRUE );
6979                           break;
6980 
6981                         case E_POS:
6982                           maxpos = gui_findlastpos( curtune )+1;
6983                           if( maxpos <= curtune->at_PosNr ) maxpos = curtune->at_PosNr+1;
6984 
6985                           setbefore_posregion( curtune, 0, curtune->at_PosNr, MAX_CHANNELS, maxpos-curtune->at_PosNr );
6986 
6987                           for( i=999; i>curtune->at_PosNr; i-- )
6988                             curtune->at_Positions[i] = curtune->at_Positions[i-1];
6989 
6990                           for( j=0; j<MAX_CHANNELS; j++ )
6991                           {
6992                             curtune->at_Positions[i].pos_Track[j]     = 0;
6993                             curtune->at_Positions[i].pos_Transpose[j] = 0;
6994                           }
6995 
6996                           setafter_posregion( curtune, 0, curtune->at_PosNr, MAX_CHANNELS, maxpos-curtune->at_PosNr );
6997                           gui_render_posed( TRUE );
6998                           break;
6999                       }
7000                       break;
7001                   }
7002                   break;
7003               }
7004               break;
7005 
7006             case IEQUALIFIER_CONTROL:
7007               chan = track = -1;
7008               if( curtune )
7009               {
7010                 chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
7011                 track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
7012               }
7013 
7014               cutting = FALSE;
7015 
7016               switch( msg->Code )
7017               {
7018                 case 1:  // Ctrl+n (set notejump to n)
7019                 case 2:
7020                 case 3:
7021                 case 4:
7022                 case 5:
7023                 case 6:
7024                 case 7:
7025                 case 8:
7026                 case 9:
7027                 case 10:
7028                   donkey = TRUE;
7029                   if( !curtune ) break;
7030 
7031                   if( curtune->at_curpanel == PN_INSED )
7032                     curtune->at_inotejump = msg->Code%10;
7033                   else
7034                     curtune->at_notejump = msg->Code%10;
7035                   break;
7036 
7037                 case 32:  // Ctrl+A (toggle voice)
7038                   if( !curtune ) break;
7039 
7040                   if( curtune->at_editing == E_POS )
7041                     chan = (curtune->at_posed_curs/5)+curtune->at_curlch;
7042                   else
7043                     chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
7044 
7045                   curtune->at_Voices[chan].vc_SetTrackOn ^= 1;
7046                   gui_render_tracked( TRUE );
7047                   break;
7048 
7049                 case 16:  // Ctrl+Q (all tracks on)
7050                   if( !curtune ) break;
7051 
7052                   for( i=0; i<MAX_CHANNELS; i++ )
7053                     curtune->at_Voices[i].vc_SetTrackOn = 1;
7054 
7055                   gui_render_tracked( TRUE );
7056                   break;
7057 
7058                 case 60:  // Ctrl+Keypad . (clear instrument)
7059                   // Have to use Ctrl because i don't like how easy this was
7060                   // to do by mistake in PT.
7061                   if( !curtune ) break;
7062                   cins = &curtune->at_Instruments[curtune->at_curins];
7063                   rp_clear_instrument( cins );
7064                 case 79:  // Ctrl+Left (instrument up)
7065                   donkey = TRUE;
7066                   if( !curtune ) break;
7067                   if( curtune->at_curins == 0 ) break;
7068 
7069                   curtune->at_curins--;
7070                   gui_render_inslist( FALSE );
7071                   gui_set_various_things( curtune );
7072                   break;
7073 
7074                 case 78:  // Ctrl+Right (instrument down)
7075                   donkey = TRUE;
7076                   if( !curtune ) break;
7077                   if( curtune->at_curins == 63 ) break;
7078 
7079                   curtune->at_curins++;
7080                   gui_render_inslist( FALSE );
7081                   gui_set_various_things( curtune );
7082                   break;
7083 
7084                 case 82:  // Ctrl+F3 (cut commands to buffer)
7085                   cutting = TRUE;
7086                 case 83:  // Ctrl+F4 (copy commands to buffer)
7087                   donkey = TRUE;
7088                   if( track == -1 ) break;
7089                   if( curtune->at_curpanel != PN_TRACKER ) break;
7090                   gui_copyregion( track, 0, curtune->at_TrackLength-1, CBF_CMD1|CBF_CMD2, cutting );
7091                   gui_render_tracked( TRUE );
7092                   break;
7093                 case 84:  // Ctrl+F5 (paste commands)
7094                   donkey = TRUE;
7095                   if( track == -1 ) break;
7096                   if( curtune->at_curpanel != PN_TRACKER ) break;
7097                   setbefore_track( curtune, track );
7098                   gui_paste( curtune, track, CBF_CMD1|CBF_CMD2 );
7099                   setafter_track( curtune, track );
7100                   gui_render_tracked( TRUE );
7101                   break;
7102                 case 65:  // Ctrl+Backspace (delete row above (commands only))
7103                   donkey = TRUE;
7104                   if( curtune == NULL ) break;
7105 
7106                   switch( curtune->at_curpanel )
7107                   {
7108                     case PN_INSED:
7109                       if( curtune->at_idoing != D_EDITING ) break;
7110 
7111                       cins = &curtune->at_Instruments[curtune->at_curins];
7112                       cple = &cins->ins_PList.pls_Entries[255];
7113 
7114                       if( cins->ins_pcury == 0 ) break;
7115 
7116                       setbefore_plist( curtune, &cins->ins_PList.pls_Entries[0] );
7117 
7118                       cins->ins_pcury--;
7119                       for( i=cins->ins_pcury; i<254; i++ )
7120                       {
7121                         cins->ins_PList.pls_Entries[i].ple_FX[0]      = cins->ins_PList.pls_Entries[i+1].ple_FX[0];
7122                         cins->ins_PList.pls_Entries[i].ple_FXParam[0] = cins->ins_PList.pls_Entries[i+1].ple_FXParam[0];
7123                         cins->ins_PList.pls_Entries[i].ple_FX[1]      = cins->ins_PList.pls_Entries[i+1].ple_FX[1];
7124                         cins->ins_PList.pls_Entries[i].ple_FXParam[1] = cins->ins_PList.pls_Entries[i+1].ple_FXParam[1];
7125                       }
7126 
7127                       cple->ple_FX[0]      = 0;
7128                       cple->ple_FXParam[0] = 0;
7129                       cple->ple_FX[1]      = 0;
7130                       cple->ple_FXParam[1] = 0;
7131 
7132                       setafter_plist( curtune, &cins->ins_PList.pls_Entries[0] );
7133 
7134                       gui_render_perf( curtune, cins, TRUE );
7135                       break;
7136 
7137                     case PN_TRACKER:
7138                       switch( curtune->at_editing )
7139                       {
7140                         case E_TRACK:
7141                           if( curtune->at_doing != D_EDITING ) break;
7142 
7143                           chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
7144                           track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
7145 
7146                           if( curtune->at_NoteNr == 0 ) break;
7147 
7148                           setbefore_track( curtune, track );
7149 
7150                           curtune->at_NoteNr--;
7151 
7152                           for( i=curtune->at_NoteNr; i<(curtune->at_TrackLength-1); i++ )
7153                           {
7154                             curtune->at_Tracks[track][i].stp_FX       = curtune->at_Tracks[track][i+1].stp_FX;
7155                             curtune->at_Tracks[track][i].stp_FXParam  = curtune->at_Tracks[track][i+1].stp_FXParam;
7156                             curtune->at_Tracks[track][i].stp_FXb      = curtune->at_Tracks[track][i+1].stp_FXb;
7157                             curtune->at_Tracks[track][i].stp_FXbParam = curtune->at_Tracks[track][i+1].stp_FXbParam;
7158                           }
7159 
7160                           curtune->at_Tracks[track][i].stp_FX         = 0;
7161                           curtune->at_Tracks[track][i].stp_FXParam    = 0;
7162                           curtune->at_Tracks[track][i].stp_FXb        = 0;
7163                           curtune->at_Tracks[track][i].stp_FXbParam   = 0;
7164 
7165                           setafter_track( curtune, track );
7166 
7167                           gui_render_tracked( TRUE );
7168                           break;
7169                       }
7170                       break;
7171                   }
7172                   break;
7173 
7174                 case 68:  // Ctrl+Enter (insert row (commands only))
7175                   donkey = TRUE;
7176                   if( curtune == NULL ) break;
7177 
7178                   switch( curtune->at_curpanel )
7179                   {
7180                     case PN_INSED:
7181                       if( curtune->at_idoing != D_EDITING ) break;
7182 
7183                       cins = &curtune->at_Instruments[curtune->at_curins];
7184                       cple = &cins->ins_PList.pls_Entries[cins->ins_pcury];
7185 
7186                       setbefore_plist( curtune, &cins->ins_PList.pls_Entries[0] );
7187 
7188                       for( i=255; i>cins->ins_pcury; i-- )
7189                       {
7190                         cins->ins_PList.pls_Entries[i].ple_FX[0]      = cins->ins_PList.pls_Entries[i-1].ple_FX[0];
7191                         cins->ins_PList.pls_Entries[i].ple_FXParam[0] = cins->ins_PList.pls_Entries[i-1].ple_FXParam[0];
7192                         cins->ins_PList.pls_Entries[i].ple_FX[1]      = cins->ins_PList.pls_Entries[i-1].ple_FX[1];
7193                         cins->ins_PList.pls_Entries[i].ple_FXParam[1] = cins->ins_PList.pls_Entries[i-1].ple_FXParam[1];
7194                       }
7195 
7196                       cple->ple_FX[0]      = 0;
7197                       cple->ple_FXParam[0] = 0;
7198                       cple->ple_FX[1]      = 0;
7199                       cple->ple_FXParam[1] = 0;
7200 
7201                       setafter_plist( curtune, &cins->ins_PList.pls_Entries[0] );
7202 
7203                       gui_render_perf( curtune, cins, TRUE );
7204                       break;
7205 
7206                     case PN_TRACKER:
7207                       switch( curtune->at_editing )
7208                       {
7209                         case E_TRACK:
7210                           if( curtune->at_doing != D_EDITING ) break;
7211 
7212                           chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
7213                           track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
7214 
7215                           setbefore_track( curtune, track );
7216 
7217                           for( i=(curtune->at_TrackLength-1); i>curtune->at_NoteNr; i-- )
7218                           {
7219                             curtune->at_Tracks[track][i].stp_FX       = curtune->at_Tracks[track][i-1].stp_FX;
7220                             curtune->at_Tracks[track][i].stp_FXParam  = curtune->at_Tracks[track][i-1].stp_FXParam;
7221                             curtune->at_Tracks[track][i].stp_FXb      = curtune->at_Tracks[track][i-1].stp_FXb;
7222                             curtune->at_Tracks[track][i].stp_FXbParam = curtune->at_Tracks[track][i-1].stp_FXbParam;
7223                           }
7224 
7225                           curtune->at_Tracks[track][i].stp_FX         = 0;
7226                           curtune->at_Tracks[track][i].stp_FXParam    = 0;
7227                           curtune->at_Tracks[track][i].stp_FXb        = 0;
7228                           curtune->at_Tracks[track][i].stp_FXbParam   = 0;
7229 
7230                           setafter_track( curtune, track );
7231 
7232                           gui_render_tracked( TRUE );
7233                           break;
7234                       }
7235                       break;
7236                   }
7237                   break;
7238               }
7239               break;
7240 
7241             case IEQUALIFIER_LALT:
7242               switch( msg->Code )
7243               {
7244                 case 16:  // Alt+Q (mute all channels)
7245                   donkey = TRUE;
7246                   if( !curtune ) break;
7247 
7248                   for( i=0; i<MAX_CHANNELS; i++ )
7249                     curtune->at_Voices[i].vc_SetTrackOn = 0;
7250                   gui_render_tracked( TRUE );
7251                   break;
7252 
7253                 case 32:  // Alt+A (mute all but the current channel)
7254                   donkey = TRUE;
7255 
7256                   if( !curtune ) break;
7257 
7258                   if( curtune->at_editing == E_POS )
7259                     chan = curtune->at_posed_curs/5;
7260                   else
7261                     chan = curtune->at_tracked_curs/9;
7262 
7263                   for( i=0; i<MAX_CHANNELS; i++ )
7264                   {
7265                     if( i == chan )
7266                       curtune->at_Voices[i].vc_SetTrackOn = 1;
7267                     else
7268                       curtune->at_Voices[i].vc_SetTrackOn = 0;
7269                   }
7270                   gui_render_tracked( TRUE );
7271                   break;
7272 
7273                 case 79:  // Alt+Left (decrement currently selected track number)
7274                   donkey = TRUE;
7275                   if( !curtune ) break;
7276 
7277                   chan = -1;
7278                   switch( curtune->at_editing )
7279                   {
7280                     case E_TRACK:
7281                       chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
7282                       break;
7283 
7284                     case E_POS:
7285                       chan  = curtune->at_posed_curs/5 + curtune->at_curlch;
7286                       break;
7287                   }
7288 
7289                   if( chan != -1 )
7290                   {
7291                     track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]-1;
7292                     if (track < 0) track = 0;
7293                     modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, track );
7294 
7295                     gui_render_posed( TRUE );
7296                     gui_render_tracked( TRUE );
7297                   }
7298                   break;
7299 
7300                 case 78:  // Alt+Right (increment currently selected track number)
7301                   donkey = TRUE;
7302                   if( !curtune ) break;
7303 
7304                   chan = -1;
7305                   switch( curtune->at_editing )
7306                   {
7307                     case E_TRACK:
7308                       chan = (curtune->at_tracked_curs/9)+curtune->at_curlch;
7309                       break;
7310 
7311                     case E_POS:
7312                       chan  = curtune->at_posed_curs/5 + curtune->at_curlch;
7313                       break;
7314                   }
7315 
7316                   if( chan != -1 )
7317                   {
7318                     track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]+1;
7319                     if (track > 255) track = 255;
7320                     modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, track );
7321 
7322                     gui_render_posed( TRUE );
7323                     gui_render_tracked( TRUE );
7324                   }
7325                   break;
7326 
7327                 case 85:  // Alt+F6 (play from pos 0)
7328                 case 86:  // Alt+F7 (play from pos 1)
7329                 case 87:  // Alt+F8 (play from pos 2)
7330                 case 88:  // Alt+F9 (play from pos 3)
7331                 case 89:  // Alt+F10 (play from pos 4)
7332                   donkey = TRUE;
7333                   if( curtune == NULL ) break;
7334 
7335                   rp_stop();
7336                   curtune->at_NoteNr = curtune->at_rempos[msg->Code-85];
7337                   if( curtune->at_NoteNr >= curtune->at_TrackLength )
7338                     curtune->at_NoteNr = curtune->at_TrackLength-1;
7339                   if( curtune->at_curpanel == PN_TRACKER )
7340                     gui_render_tracked( TRUE );
7341 
7342                   curtune->at_doing = D_IDLE;
7343                   if( rp_play_pos( curtune, TRUE ) )
7344                     curtune->at_doing = D_PLAYING;
7345                   break;
7346               }
7347               break;
7348 
7349             case IEQUALIFIER_LCOMMAND:
7350               break;
7351           }
7352 
7353           if( curtune != NULL )
7354           {
7355             for( i=0; i<10; i++ )
7356             {
7357               if( msg->Code == inskeys[i] )
7358               {
7359                 donkey = TRUE;
7360                 curtune->at_curins = curtune->at_baseins+i;
7361                 if( curtune->at_curins > 63 ) curtune->at_curins = 63;
7362                 gui_render_inslist( FALSE );
7363                 gui_set_various_things( curtune );
7364 
7365                 if( curtune->at_drumpadmode )
7366                 {
7367                   chan = curtune->at_tracked_curs/9+curtune->at_curlch;
7368 
7369                   if( curtune->at_curins > 0 )
7370                     rp_play_note( curtune, curtune->at_curins, curtune->at_drumpadnote, chan );
7371                   if( curtune->at_doing == D_EDITING )
7372                   {
7373                     stp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr];
7374                     modify_stp_w( curtune, stp, UNT_STP_NOTEANDINS, (curtune->at_drumpadnote<<8)|curtune->at_curins );
7375                     curtune->at_NoteNr += curtune->at_notejump;
7376                     curtune->at_modified = TRUE;
7377                     while( curtune->at_NoteNr >= curtune->at_TrackLength )
7378                       curtune->at_NoteNr -= curtune->at_TrackLength;
7379                     gui_render_tracked( TRUE );
7380                   }
7381                 }
7382 
7383                 break;
7384               }
7385             }
7386           }
7387 
7388           if( donkey ) break;
7389 
7390           if( curtune == NULL )
7391             panel = PN_TRACKER;
7392           else
7393             panel = curtune->at_curpanel;
7394 
7395           switch( panel )
7396           {
7397             case PN_TRACKER:
7398               switch( msg->Code )
7399               {
7400                 case 64:
7401                   donkey = TRUE;
7402                   rp_stop();
7403                   gui_render_tracked( TRUE );  // Kill the VUMeters
7404                   gui_render_wavemeter();
7405 
7406                   if( curtune->at_doing == D_EDITING )
7407                     curtune->at_doing = D_IDLE;
7408                   else
7409                     curtune->at_doing = D_EDITING;
7410                   gui_render_tracker( TRUE );
7411                   break;
7412                 case 68:
7413                   donkey = TRUE;
7414                   if( curtune == NULL ) break;
7415 
7416                   if( curtune->at_editing == E_POS )
7417                     curtune->at_editing = E_TRACK;
7418                   else
7419                     curtune->at_editing = E_POS;
7420                   gui_render_tracker( TRUE );
7421                   break;
7422                 case 79:
7423                   donkey = TRUE;
7424                   if( curtune == NULL ) break;
7425 
7426                   switch( curtune->at_editing )
7427                   {
7428                     case E_POS:
7429                       curtune->at_posed_curs--;
7430                       if( curtune->at_curlch == 0 )
7431                       {
7432                         if( curtune->at_posed_curs < 0 )
7433                           curtune->at_posed_curs = curtune->at_Channels*5-1;
7434 
7435                         while( (curtune->at_posed_curs/5) > 5 )
7436                         {
7437                           curtune->at_posed_curs -= 5;
7438                           curtune->at_curlch++;
7439                         }
7440                       } else {
7441                         while( curtune->at_posed_curs < 0 )
7442                         {
7443                           curtune->at_curlch--;
7444                           curtune->at_posed_curs += 5;
7445                         }
7446                       }
7447 
7448                       gui_render_tracker( TRUE );
7449                       break;
7450                     case E_TRACK:
7451                       curtune->at_tracked_curs--;
7452                       if( curtune->at_curlch == 0 )
7453                       {
7454                         if( curtune->at_tracked_curs < 0 )
7455                           curtune->at_tracked_curs = curtune->at_Channels*9-1;
7456 
7457                         while( (curtune->at_tracked_curs/9) > 5 )
7458                         {
7459                           curtune->at_tracked_curs -= 9;
7460                           curtune->at_curlch++;
7461                         }
7462                       } else {
7463                         while( curtune->at_tracked_curs < 0 )
7464                         {
7465                           curtune->at_curlch--;
7466                           curtune->at_tracked_curs += 9;
7467                         }
7468                       }
7469 
7470                       gui_render_tracker( TRUE );
7471                       break;
7472                   }
7473                   break;
7474                 case 78:
7475                   donkey = TRUE;
7476                   if( curtune == NULL ) break;
7477 
7478                   switch( curtune->at_editing )
7479                   {
7480                     case E_POS:
7481                       gui_posed_moveright();
7482                       gui_render_tracker( TRUE );
7483                       break;
7484                     case E_TRACK:
7485                       curtune->at_tracked_curs++;
7486 
7487                       if( (curtune->at_tracked_curs/9+curtune->at_curlch) >= curtune->at_Channels )
7488                       {
7489                         curtune->at_tracked_curs = 0;
7490                         curtune->at_curlch = 0;
7491                       }
7492 
7493                       while( (curtune->at_tracked_curs/9) > 5 )
7494                       {
7495                         curtune->at_curlch++;
7496                         curtune->at_tracked_curs -= 9;
7497                       }
7498 
7499                       gui_render_tracker( TRUE );
7500                       break;
7501                   }
7502                   break;
7503                 case 66:
7504                   donkey = TRUE;
7505                   if( curtune == NULL ) break;
7506 
7507                   switch( curtune->at_editing )
7508                   {
7509                     case E_POS:
7510                       i = 0;
7511                       switch( qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_CONTROL) )
7512                       {
7513                         case IEQUALIFIER_CONTROL:
7514                           i = (curtune->at_posed_curs%5) > 2 ? 3 : 0;
7515                         case 0:
7516                           curtune->at_posed_curs = ((curtune->at_posed_curs+5)/5)*5;
7517 
7518                           if( (curtune->at_posed_curs/5)+curtune->at_curlch >= curtune->at_Channels )
7519                           {
7520                             curtune->at_posed_curs = 0;
7521                             curtune->at_curlch = 0;
7522                           }
7523 
7524                           while( (curtune->at_posed_curs/5) > 5 )
7525                           {
7526                             curtune->at_posed_curs -= 5;
7527                             curtune->at_curlch++;
7528                           }
7529 
7530                           curtune->at_posed_curs += i;
7531                           break;
7532 
7533                         case IEQUALIFIER_LSHIFT|IEQUALIFIER_CONTROL:
7534                           i = (curtune->at_posed_curs%5) > 2 ? 3 : 0;
7535                         case IEQUALIFIER_LSHIFT:
7536                           if( curtune->at_posed_curs < 5 )
7537                           {
7538                             if( curtune->at_curlch > 0 )
7539                             {
7540                               curtune->at_curlch--;
7541                               curtune->at_posed_curs = 0;
7542                             } else {
7543                               curtune->at_posed_curs = 5*5;
7544                               curtune->at_curlch = curtune->at_Channels-6;
7545                               if( curtune->at_curlch < 0 )
7546                               {
7547                                 curtune->at_curlch = 0;
7548                                 curtune->at_posed_curs = (curtune->at_Channels-1)*5;
7549                               }
7550                             }
7551                           } else {
7552                             curtune->at_posed_curs = ((curtune->at_posed_curs-5)/5)*5;
7553                           }
7554                           curtune->at_posed_curs += i;
7555                           break;
7556                       }
7557 
7558                       gui_render_tracker( TRUE );
7559                       break;
7560                     case E_TRACK:
7561                       i = 0;
7562                       switch( qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_CONTROL) )
7563                       {
7564                         case IEQUALIFIER_CONTROL:
7565                           j = curtune->at_tracked_curs%9;
7566                           if(( j > 0 ) && ( j < 3 )) i = 1;
7567                           if(( j > 2 ) && ( j < 6 )) i = 3;
7568                           if( j > 5 ) i = 6;
7569                         case 0:
7570                           curtune->at_tracked_curs = ((curtune->at_tracked_curs+9)/9)*9;
7571 
7572                           if( (curtune->at_tracked_curs/9)+curtune->at_curlch >= curtune->at_Channels )
7573                           {
7574                             curtune->at_tracked_curs = 0;
7575                             curtune->at_curlch = 0;
7576                           }
7577 
7578                           while( (curtune->at_tracked_curs/9) > 5 )
7579                           {
7580                             curtune->at_tracked_curs -= 9;
7581                             curtune->at_curlch++;
7582                           }
7583                           curtune->at_tracked_curs += i;
7584                           break;
7585 
7586                         case IEQUALIFIER_LSHIFT|IEQUALIFIER_CONTROL:
7587                           j = curtune->at_tracked_curs%9;
7588                           if(( j > 0 ) && ( j < 3 )) i = 1;
7589                           if(( j > 2 ) && ( j < 6 )) i = 3;
7590                           if( j > 5 ) i = 6;
7591                         case IEQUALIFIER_LSHIFT:
7592                           if( curtune->at_tracked_curs < 9 )
7593                           {
7594                             if( curtune->at_curlch > 0 )
7595                             {
7596                               curtune->at_curlch--;
7597                               curtune->at_tracked_curs = 0;
7598                             } else {
7599                               curtune->at_tracked_curs = 5*9;
7600                               curtune->at_curlch = curtune->at_Channels-6;
7601                               if( curtune->at_curlch < 0 )
7602                               {
7603                                 curtune->at_curlch = 0;
7604                                 curtune->at_tracked_curs = (curtune->at_Channels-1)*9;
7605                               }
7606                             }
7607                           } else {
7608                             curtune->at_tracked_curs = ((curtune->at_tracked_curs-9)/9)*9;
7609                           }
7610                           curtune->at_tracked_curs += i;
7611                           break;
7612                       }
7613 
7614                       gui_render_tracker( TRUE );
7615                       break;
7616                   }
7617                   break;
7618               }
7619 
7620               switch( curtune->at_doing )
7621               {
7622                 case D_EDITING:
7623                 case D_IDLE:
7624                   if( curtune == NULL )
7625                     break;
7626 
7627                   for( i=0; i<16; i++ )
7628                     if( msg->Code == hexkeys[i] )
7629                       break;
7630 
7631                   if( ( i < 16 ) && ( (qual&IEQUALIFIER_CONTROL) == 0 ) )
7632                   {
7633                     switch( curtune->at_editing )
7634                     {
7635                       case E_TRACK:
7636                         if( curtune->at_doing == D_IDLE ) break;
7637                         if( ( curtune->at_tracked_curs%9 ) == 0 ) break;
7638 
7639                         donkey = TRUE;
7640 
7641                         chan = curtune->at_tracked_curs/9 + curtune->at_curlch;
7642                         stp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr];
7643 
7644                         switch( curtune->at_tracked_curs%9 )
7645                         {
7646                           case 1:
7647                             if( i>9 ) break;
7648                             curtune->at_modified = TRUE;
7649                             j = (stp->stp_Instrument%10)+(i*10);
7650                             if( j > 63 ) j = 63;
7651                             modify_stp_b( curtune, stp, UNT_STP_INSTRUMENT, j );
7652                             stp->stp_Instrument = j;
7653                             break;
7654                           case 2:
7655                             if( i>9 ) break;
7656                             curtune->at_modified = TRUE;
7657                             j = (stp->stp_Instrument/10)*10+i;
7658                             if( j > 63 ) j = 63;
7659                             modify_stp_b( curtune, stp, UNT_STP_INSTRUMENT, j );
7660                             break;
7661                           case 3:
7662                             curtune->at_modified = TRUE;
7663                             modify_stp_b( curtune, stp, UNT_STP_FX, i );
7664                             break;
7665                           case 4:
7666                             curtune->at_modified = TRUE;
7667                             modify_stp_b( curtune, stp, UNT_STP_FXPARAM, (stp->stp_FXParam&0xf)|(i<<4) );
7668                             break;
7669                           case 5:
7670                             curtune->at_modified = TRUE;
7671                             modify_stp_b( curtune, stp, UNT_STP_FXPARAM, (stp->stp_FXParam&0xf0)|i );
7672                             break;
7673                           case 6:
7674                             curtune->at_modified = TRUE;
7675                             modify_stp_b( curtune, stp, UNT_STP_FXB, i );
7676                             break;
7677                           case 7:
7678                             curtune->at_modified = TRUE;
7679                             modify_stp_b( curtune, stp, UNT_STP_FXBPARAM, (stp->stp_FXbParam&0xf)|(i<<4) );
7680                             break;
7681                           case 8:
7682                             curtune->at_modified = TRUE;
7683                             modify_stp_b( curtune, stp, UNT_STP_FXBPARAM, (stp->stp_FXbParam&0xf0)|i );
7684                             break;
7685                         }
7686 
7687                         curtune->at_NoteNr += curtune->at_notejump;
7688                         if( curtune->at_NoteNr >= curtune->at_TrackLength )
7689                           curtune->at_NoteNr = 0;
7690                         gui_render_tracker( TRUE );
7691                         break;
7692                       case E_POS:
7693                         donkey = TRUE;
7694                         chan  = curtune->at_posed_curs/5 + curtune->at_curlch;
7695                         track = (curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff);
7696                         tran  = (curtune->at_Positions[curtune->at_PosNr].pos_Transpose[chan]&0xff);
7697                         switch( curtune->at_posed_curs%5 )
7698                         {
7699                           case 0:
7700                             if( i > 9 ) break;
7701                             curtune->at_modified = TRUE;
7702                             j = (track%100)+(i*100);
7703                             if( j > 255 ) j = 255;
7704                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, j );
7705                             break;
7706                           case 1:
7707                             if( i > 9 ) break;
7708                             curtune->at_modified = TRUE;
7709                             j = ((track/100)*100)+(track%10)+(i*10);
7710                             if( j > 255 ) j = 255;
7711                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, j );
7712                             break;
7713                           case 2:
7714                             if( i > 9 ) break;
7715                             curtune->at_modified = TRUE;
7716                             j = ((track/100)*100)+(((track%100)/10)*10)+i;
7717                             if( j > 255 ) j = 255;
7718                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, j );
7719                             break;
7720                           case 3:
7721                             j = (tran & 0x0f)|(i<<4);
7722                             curtune->at_modified = TRUE;
7723                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRANS, j );
7724                             break;
7725                           case 4:
7726                             j = (tran & 0xf0)|i;
7727                             curtune->at_modified = TRUE;
7728                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRANS, j );
7729                             break;
7730                         }
7731                         if( posedadvance ) gui_posed_moveright();
7732                         gui_render_tracker( TRUE );
7733                         break;
7734                     }
7735                   }
7736 
7737                   if( donkey ) break;
7738 
7739                   if( ( curtune->at_editing == E_TRACK ) &&
7740                       ( (qual&IEQUALIFIER_CONTROL) == 0 ) &&
7741                       ( (curtune->at_tracked_curs%9) == 0 ) )
7742                   {
7743                     // Piano!
7744                     for( i=0; i<29; i++ )
7745                     {
7746                       if( ( msg->Code == pianokeys[i] ) ||
7747                           ( ( extrakeys[i] != -1 ) && ( msg->Code == extrakeys[i] ) ) )
7748                       {
7749                         donkey = TRUE;
7750                         chan = curtune->at_tracked_curs/9+curtune->at_curlch;
7751 
7752                         j = i+basekey+1;
7753                         if( j > 60 ) break;
7754 
7755                         curtune->at_drumpadnote = j;
7756 
7757                         if( curtune->at_curins > 0 )
7758                           rp_play_note( curtune, curtune->at_curins, i+basekey+1, chan );
7759                         if( curtune->at_doing == D_EDITING )
7760                         {
7761                           stp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr];
7762                           modify_stp_w( curtune, stp, UNT_STP_NOTEANDINS, ((i+basekey+1)<<8)|curtune->at_curins );
7763                           curtune->at_NoteNr += curtune->at_notejump;
7764                           curtune->at_modified = TRUE;
7765                           while( curtune->at_NoteNr >= curtune->at_TrackLength )
7766                             curtune->at_NoteNr -= curtune->at_TrackLength;
7767                           gui_render_tracked( TRUE );
7768                         }
7769                         break;
7770                       }
7771                     }
7772                   }
7773 
7774                   if( donkey ) break;
7775 
7776                   if( qual&IEQUALIFIER_CONTROL )
7777                   {
7778                     cutting = FALSE;
7779                     switch( msg->Code )
7780                     {
7781                       case 19:  // Ctrl+R (restore positions)
7782                         donkey = TRUE;
7783                         if( curtune ) gui_set_rempos( curtune );
7784                         gui_render_tracked( TRUE );
7785                         break;
7786                       case 21:  // Ctrl+Y (reverse block)
7787                         donkey = TRUE;
7788                         if( !curtune ) break;
7789 
7790                         if( curtune->at_cbmarktrack != -1 )
7791                         {
7792                           struct ahx_step tmpstp;
7793 
7794                           track = curtune->at_cbmarktrack;
7795 
7796                           setbefore_track( curtune, track );
7797 
7798                           j = ((curtune->at_cbmarkendnote-curtune->at_cbmarkstartnote)+1)>>1;
7799                           k = curtune->at_cbmarkstartnote;
7800                           l = curtune->at_cbmarkendnote;
7801                           for( i=0; i<j; i++ )
7802                           {
7803                             if( curtune->at_cbmarkbits & CBF_NOTES )
7804                             {
7805                               tmpstp.stp_Note       = curtune->at_Tracks[track][k].stp_Note;
7806                               tmpstp.stp_Instrument = curtune->at_Tracks[track][k].stp_Instrument;
7807                               curtune->at_Tracks[track][k].stp_Note       = curtune->at_Tracks[track][l].stp_Note;
7808                               curtune->at_Tracks[track][k].stp_Instrument = curtune->at_Tracks[track][l].stp_Instrument;
7809                               curtune->at_Tracks[track][l].stp_Note       = tmpstp.stp_Note;
7810                               curtune->at_Tracks[track][l].stp_Instrument = tmpstp.stp_Instrument;
7811                             }
7812                             if( curtune->at_cbmarkbits & CBF_CMD1 )
7813                             {
7814                               tmpstp.stp_FX      = curtune->at_Tracks[track][k].stp_FX;
7815                               tmpstp.stp_FXParam = curtune->at_Tracks[track][k].stp_FXParam;
7816                               curtune->at_Tracks[track][k].stp_FX         = curtune->at_Tracks[track][l].stp_FX;
7817                               curtune->at_Tracks[track][k].stp_FXParam    = curtune->at_Tracks[track][l].stp_FXParam;
7818                               curtune->at_Tracks[track][l].stp_FX         = tmpstp.stp_FX;
7819                               curtune->at_Tracks[track][l].stp_FXParam    = tmpstp.stp_FXParam;
7820                             }
7821                             if( curtune->at_cbmarkbits & CBF_CMD2 )
7822                             {
7823                               tmpstp.stp_FXb        = curtune->at_Tracks[track][k].stp_FXb;
7824                               tmpstp.stp_FXbParam   = curtune->at_Tracks[track][k].stp_FXbParam;
7825                               curtune->at_Tracks[track][k].stp_FXb        = curtune->at_Tracks[track][l].stp_FXb;
7826                               curtune->at_Tracks[track][k].stp_FXbParam   = curtune->at_Tracks[track][l].stp_FXbParam;
7827                               curtune->at_Tracks[track][l].stp_FXb        = tmpstp.stp_FXb;
7828                               curtune->at_Tracks[track][l].stp_FXbParam   = tmpstp.stp_FXbParam;
7829                             }
7830                             k++;
7831                             l--;
7832                           }
7833 
7834                           setafter_track( curtune, track );
7835 
7836                         } else {
7837                           struct ahx_step tmpstp;
7838 
7839                           chan = curtune->at_tracked_curs/9+curtune->at_curlch;
7840                           track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
7841 
7842                           setbefore_track( curtune, track );
7843 
7844                           j = curtune->at_TrackLength>>1;
7845                           k = curtune->at_TrackLength-1;
7846                           for( i=0; i<j; i++ )
7847                           {
7848                             tmpstp = curtune->at_Tracks[track][i];
7849                             curtune->at_Tracks[track][i]   = curtune->at_Tracks[track][k-i];
7850                             curtune->at_Tracks[track][k-i] = tmpstp;
7851                           }
7852 
7853                           setafter_track( curtune, track );
7854                         }
7855 
7856                         gui_render_tracked( TRUE );
7857                         break;
7858 
7859                       case 24:  // Ctrl+O (squish)
7860                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
7861                         if( curtune->at_editing != E_TRACK ) break;
7862                         if( cb_length == 0 ) break;
7863 
7864                         chan = curtune->at_tracked_curs/9+curtune->at_curlch;
7865                         track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
7866 
7867                         if( i == curtune->at_TrackLength-1 ) break;
7868 
7869                         setbefore_track( curtune, track );
7870 
7871                         for( i=curtune->at_NoteNr+1; i<curtune->at_TrackLength; i++ )
7872                         {
7873                           for( j=i; j<(curtune->at_TrackLength-1); j++ )
7874                             curtune->at_Tracks[track][j] = curtune->at_Tracks[track][j+1];
7875                           curtune->at_Tracks[track][curtune->at_TrackLength-1].stp_Note       = 0;
7876                           curtune->at_Tracks[track][curtune->at_TrackLength-1].stp_Instrument = 0;
7877                           curtune->at_Tracks[track][curtune->at_TrackLength-1].stp_FX         = 0;
7878                           curtune->at_Tracks[track][curtune->at_TrackLength-1].stp_FXParam    = 0;
7879                           curtune->at_Tracks[track][curtune->at_TrackLength-1].stp_FXb        = 0;
7880                           curtune->at_Tracks[track][curtune->at_TrackLength-1].stp_FXbParam   = 0;
7881                         }
7882 
7883                         setafter_track( curtune, track );
7884 
7885                         gui_render_tracked( TRUE );
7886                         break;
7887 
7888                       case 23:  // Ctrl+I (Insert block)
7889                         donkey = TRUE;
7890                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
7891                         if( curtune->at_editing != E_TRACK ) break;
7892                         if( cb_length == 0 ) break;
7893 
7894                         chan = curtune->at_tracked_curs/9+curtune->at_curlch;
7895                         track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
7896 
7897                         setbefore_track( curtune, track );
7898 
7899                         for( i=curtune->at_TrackLength-1; i>=curtune->at_NoteNr+cb_length; i-- )
7900                         {
7901                           if( cb_contains & CBF_NOTES )
7902                           {
7903                             curtune->at_Tracks[track][i].stp_Note       = curtune->at_Tracks[track][i-cb_length].stp_Note;
7904                             curtune->at_Tracks[track][i].stp_Instrument = curtune->at_Tracks[track][i-cb_length].stp_Instrument;
7905                           }
7906                           if( cb_contains & CBF_CMD1 )
7907                           {
7908                             curtune->at_Tracks[track][i].stp_FX         = curtune->at_Tracks[track][i-cb_length].stp_FX;
7909                             curtune->at_Tracks[track][i].stp_FXParam    = curtune->at_Tracks[track][i-cb_length].stp_FXParam;
7910                           }
7911                           if( cb_contains & CBF_CMD2 )
7912                           {
7913                             curtune->at_Tracks[track][i].stp_FXb        = curtune->at_Tracks[track][i-cb_length].stp_FXb;
7914                             curtune->at_Tracks[track][i].stp_FXbParam   = curtune->at_Tracks[track][i-cb_length].stp_FXbParam;
7915                           }
7916                         }
7917 
7918                         gui_paste( curtune, track, CBF_NOTES|CBF_CMD1|CBF_CMD2 );
7919 
7920                         setafter_track( curtune, track );
7921 
7922                         gui_render_tracked( TRUE );
7923                         break;
7924 
7925                       case 34:  // Ctrl+D (Delete block)
7926                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
7927                         if( curtune->at_editing != E_TRACK ) break;
7928                         if( curtune->at_cbmarktrack == -1 ) break;
7929 
7930                         donkey = TRUE;
7931 
7932                         setbefore_track( curtune, curtune->at_cbmarktrack );
7933 
7934                         j = (curtune->at_cbmarkendnote - curtune->at_cbmarkstartnote) + 1;
7935 
7936                         for( i=curtune->at_cbmarkstartnote; i<curtune->at_TrackLength-j; i++ )
7937                         {
7938                           if( curtune->at_cbmarkbits & CBF_NOTES )
7939                           {
7940                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note       = curtune->at_Tracks[curtune->at_cbmarktrack][i+j].stp_Note;
7941                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Instrument = curtune->at_Tracks[curtune->at_cbmarktrack][i+j].stp_Instrument;
7942                           }
7943                           if( curtune->at_cbmarkbits & CBF_CMD1 )
7944                           {
7945                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FX         = curtune->at_Tracks[curtune->at_cbmarktrack][i+j].stp_FX;
7946                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FXParam    = curtune->at_Tracks[curtune->at_cbmarktrack][i+j].stp_FXParam;
7947                           }
7948                           if( curtune->at_cbmarkbits & CBF_CMD2 )
7949                           {
7950                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FXb        = curtune->at_Tracks[curtune->at_cbmarktrack][i+j].stp_FXb;
7951                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FXbParam   = curtune->at_Tracks[curtune->at_cbmarktrack][i+j].stp_FXbParam;
7952                           }
7953                         }
7954 
7955                         for( ; i<curtune->at_TrackLength; i++ )
7956                         {
7957                           if( curtune->at_cbmarkbits & CBF_NOTES )
7958                           {
7959                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note       = 0;
7960                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Instrument = 0;
7961                           }
7962                           if( curtune->at_cbmarkbits & CBF_CMD1 )
7963                           {
7964                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FX         = 0;
7965                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FXParam    = 0;
7966                           }
7967                           if( curtune->at_cbmarkbits & CBF_CMD2 )
7968                           {
7969                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FXb        = 0;
7970                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_FXbParam   = 0;
7971                           }
7972                         }
7973 
7974                         setafter_track( curtune, curtune->at_cbmarktrack );
7975 
7976                         curtune->at_cbmarktrack = -1;
7977 
7978                         gui_render_tracked( TRUE );
7979                         break;
7980 
7981                       case 37:  // Ctrl+H (transpose block up)
7982                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
7983                         if( curtune->at_editing != E_TRACK ) break;
7984                         if( curtune->at_cbmarktrack == -1 ) break;
7985                         if( ( curtune->at_cbmarkbits & CBF_NOTES ) == 0 ) break;
7986 
7987                         donkey = TRUE;
7988 
7989                         setbefore_track( curtune, curtune->at_cbmarktrack );
7990 
7991                         for( i=curtune->at_cbmarkstartnote; i<=curtune->at_cbmarkendnote; i++ )
7992                           if( ( curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note < 60 ) &&
7993                               ( curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note > 0 ) )
7994                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note++;
7995 
7996                         setafter_track( curtune, curtune->at_cbmarktrack );
7997 
7998                         gui_render_tracked( TRUE );
7999                         break;
8000 
8001                      case 40:  // Ctrl+L (transpose block down)
8002                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
8003                         if( curtune->at_editing != E_TRACK ) break;
8004                         if( curtune->at_cbmarktrack == -1 ) break;
8005                         if( ( curtune->at_cbmarkbits & CBF_NOTES ) == 0 ) break;
8006 
8007                         donkey = TRUE;
8008 
8009                         setbefore_track( curtune, curtune->at_cbmarktrack );
8010 
8011                         for( i=curtune->at_cbmarkstartnote; i<=curtune->at_cbmarkendnote; i++ )
8012                           if( curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note > 1 )
8013                             curtune->at_Tracks[curtune->at_cbmarktrack][i].stp_Note--;
8014 
8015                         setafter_track( curtune, curtune->at_cbmarktrack );
8016 
8017                         gui_render_tracked( TRUE );
8018                         break;
8019 
8020                       case 39:  // Ctrl+K (kill to end/start of track)
8021                         chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8022                         track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
8023 
8024                         if( qual & IEQUALIFIER_LSHIFT )
8025                         {
8026                           setbefore_track( curtune, track );
8027                           for( i=0; i<=curtune->at_NoteNr; i++ )
8028                           {
8029                             curtune->at_Tracks[track][i].stp_Note       = 0;
8030                             curtune->at_Tracks[track][i].stp_Instrument = 0;
8031                             curtune->at_Tracks[track][i].stp_FX         = 0;
8032                             curtune->at_Tracks[track][i].stp_FXParam    = 0;
8033                             curtune->at_Tracks[track][i].stp_FXb        = 0;
8034                             curtune->at_Tracks[track][i].stp_FXbParam   = 0;
8035                           }
8036                           setafter_track( curtune, track );
8037                           gui_render_tracked( TRUE );
8038                           break;
8039                         }
8040 
8041                         setbefore_track( curtune, track );
8042                         for( i=curtune->at_NoteNr; i<curtune->at_TrackLength; i++ )
8043                         {
8044                           curtune->at_Tracks[track][i].stp_Note       = 0;
8045                           curtune->at_Tracks[track][i].stp_Instrument = 0;
8046                           curtune->at_Tracks[track][i].stp_FX         = 0;
8047                           curtune->at_Tracks[track][i].stp_FXParam    = 0;
8048                           curtune->at_Tracks[track][i].stp_FXb        = 0;
8049                           curtune->at_Tracks[track][i].stp_FXbParam   = 0;
8050                         }
8051                         setafter_track( curtune, track );
8052                         gui_render_tracked( TRUE );
8053                         break;
8054 
8055                       case 22:  // Ctrl+U (Undo)
8056                         rp_stop();
8057                         gui_render_wavemeter();
8058                         curtune->at_doing = D_IDLE;
8059                         if( qual & IEQUALIFIER_LSHIFT )
8060                           redo( curtune );
8061                         else
8062                           undo( curtune );
8063                         break;
8064 
8065                       case 50:  // Cut
8066                         cutting = TRUE;
8067                       case 51:  // Copy
8068                         donkey = TRUE;
8069                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
8070 
8071                         switch( curtune->at_editing )
8072                         {
8073                           case E_TRACK:
8074                             if( curtune->at_cbmarktrack == -1 ) break;
8075 
8076                             if( cutting ) setbefore_track( curtune, curtune->at_cbmarktrack );
8077                             gui_copyregion( curtune->at_cbmarktrack, curtune->at_cbmarkstartnote, curtune->at_cbmarkendnote, curtune->at_cbmarkbits, cutting );
8078                             if( cutting ) setafter_track( curtune, curtune->at_cbmarktrack );
8079                             curtune->at_cbmarktrack = -1;
8080 
8081                             gui_render_tracked( TRUE );
8082                             break;
8083 
8084                           case E_POS:
8085                             if( curtune->at_cbpmarklft == -1 ) break;
8086 
8087                             gui_copyposregion( curtune, cutting );
8088                             curtune->at_cbpmarkmarklft = -1;
8089                             curtune->at_cbpmarklft = -1;
8090                             gui_render_posed( TRUE );
8091                             if( cutting ) gui_render_tracked( TRUE );
8092                             break;
8093                         }
8094                         break;
8095 
8096                       case 25:  // Paste
8097                       case 52:  // V as well as P
8098                         donkey = TRUE;
8099                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
8100 
8101                         switch( curtune->at_editing )
8102                         {
8103                           case E_TRACK:
8104                             chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8105                             track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
8106                             setbefore_track( curtune, track );
8107                             gui_paste( curtune, track, CBF_NOTES|CBF_CMD1|CBF_CMD2 );
8108                             setafter_track( curtune, track );
8109                             gui_render_tracked( TRUE );
8110                             break;
8111 
8112                           case E_POS:
8113                             gui_pasteposregion( curtune );
8114                             gui_render_posed( TRUE );
8115                             gui_render_tracked( TRUE );
8116                             break;
8117                         }
8118                         break;
8119 
8120                       case 53:  // Ctrl+B Mark
8121                         donkey = TRUE;
8122                         if( ( curtune->at_doing != D_EDITING ) && ( curtune->at_doing != D_IDLE ) ) break;
8123 
8124                         switch( curtune->at_editing )
8125                         {
8126                           case E_TRACK:
8127                             if( curtune->at_cbmarktrack != -1 )
8128                             {
8129                               curtune->at_cbmarktrack = -1;
8130                               gui_render_tracked( TRUE );
8131                               break;
8132                             }
8133 
8134                             chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8135                             track = curtune->at_Positions[curtune->at_PosNr].pos_Track[chan];
8136 
8137                             curtune->at_cbmarktrack     = track;
8138                             curtune->at_cbmarkmarknote  = curtune->at_NoteNr;
8139                             curtune->at_cbmarkcurnote   = curtune->at_NoteNr;
8140                             curtune->at_cbmarkmarkx     = curtune->at_tracked_curs%9;
8141                             curtune->at_cbmarkcurx      = curtune->at_tracked_curs%9;
8142 
8143                             gui_render_tracked( TRUE );
8144                             break;
8145 
8146                           case E_POS:
8147                             if( curtune->at_cbpmarkmarklft != -1 )
8148                             {
8149                               curtune->at_cbpmarkmarklft = -1;
8150                               gui_render_posed( TRUE );
8151                               break;
8152                             }
8153 
8154                             curtune->at_cbpmarkmarkpos = curtune->at_PosNr;
8155                             curtune->at_cbpmarkmarklft = (((curtune->at_posed_curs/5)+curtune->at_curlch)<<1)|((curtune->at_posed_curs%5)>2?1:0);
8156                             gui_render_posed( TRUE );
8157                             break;
8158                         }
8159                         break;
8160                     }
8161                   }
8162 
8163                   if( donkey ) break;
8164 
8165                   switch( msg->Code )
8166                   {
8167                     case 11:
8168                       switch( curtune->at_editing )
8169                       {
8170                         case E_TRACK:
8171                           if( curtune->at_doing != D_EDITING ) break;
8172 
8173                           if( (curtune->at_tracked_curs%9) > 2 )
8174                           {
8175                             donkey = TRUE;
8176                             chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8177                             stp  = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr];
8178                             if( curtune->at_NoteNr > 0 )
8179                               pstp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr-1];
8180                             else
8181                               pstp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_TrackLength-1];
8182 
8183                             if( (curtune->at_tracked_curs%9) < 6 )
8184                             {
8185                               modify_stp_w( curtune, stp, UNT_STP_FXANDPARAM, (pstp->stp_FX<<8)|((pstp->stp_FXParam-1)&0xff) );
8186                             } else {
8187                               modify_stp_w( curtune, stp, UNT_STP_FXBANDPARAM, (pstp->stp_FXb<<8)|((pstp->stp_FXbParam-1)&0xff) );
8188                             }
8189 
8190                             curtune->at_NoteNr += curtune->at_notejump;
8191                             curtune->at_modified = TRUE;
8192                             if( curtune->at_NoteNr >= curtune->at_TrackLength )
8193                               curtune->at_NoteNr = 0;
8194                             gui_render_tracker( FALSE );
8195                           }
8196                           break;
8197                         case E_POS:
8198                           if( curtune->at_PosNr == 0 ) break;
8199 
8200                           chan = curtune->at_posed_curs/5 + curtune->at_curlch;
8201 
8202                           donkey = TRUE;
8203 
8204                           switch( curtune->at_posed_curs%5 )
8205                           {
8206                             case 0:
8207                             case 1:
8208                             case 2:
8209                               modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, (curtune->at_Positions[curtune->at_PosNr-1].pos_Track[chan]-1)&0xff );
8210                               curtune->at_PosNr++;
8211                               if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8212                               gui_render_posed( FALSE );
8213                               break;
8214                             default:
8215                               modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRANS, (curtune->at_Positions[curtune->at_PosNr-1].pos_Transpose[chan]-1)&0xff );
8216                               curtune->at_PosNr++;
8217                               if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8218                               gui_render_posed( FALSE );
8219                               break;
8220 
8221                           }
8222                           break;
8223                       }
8224                       break;
8225 
8226                     case 12:
8227                       switch( curtune->at_editing )
8228                       {
8229                         case E_TRACK:
8230                           if( curtune->at_doing != D_EDITING ) break;
8231 
8232                           if( (curtune->at_tracked_curs%9) > 2 )
8233                           {
8234                             donkey = TRUE;
8235                             chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8236                             stp  = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr];
8237                             if( curtune->at_NoteNr > 0 )
8238                               pstp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr-1];
8239                             else
8240                               pstp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_TrackLength-1];
8241 
8242                             if( (curtune->at_tracked_curs%9) < 6 )
8243                             {
8244                               modify_stp_w( curtune, stp, UNT_STP_FXANDPARAM, (pstp->stp_FX<<8)|((pstp->stp_FXParam+1)&0xff) );
8245                             } else {
8246                               modify_stp_w( curtune, stp, UNT_STP_FXBANDPARAM, (pstp->stp_FXb<<8)|((pstp->stp_FXbParam+1)&0xff) );
8247                             }
8248 
8249                             curtune->at_NoteNr += curtune->at_notejump;
8250                             curtune->at_modified = TRUE;
8251                             if( curtune->at_NoteNr >= curtune->at_TrackLength )
8252                               curtune->at_NoteNr = 0;
8253                             gui_render_tracker( FALSE );
8254                           }
8255                           break;
8256                         case E_POS:
8257                           if( curtune->at_PosNr == 0 ) break;
8258 
8259                           chan = curtune->at_posed_curs/5 + curtune->at_curlch;
8260 
8261                           donkey = TRUE;
8262 
8263                           switch( curtune->at_posed_curs%5 )
8264                           {
8265                             case 0:
8266                             case 1:
8267                             case 2:
8268                               modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, (curtune->at_Positions[curtune->at_PosNr-1].pos_Track[chan]+1)&0xff );
8269                               curtune->at_PosNr++;
8270                               if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8271                               gui_render_posed( FALSE );
8272                               break;
8273                             default:
8274                               modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRANS, (curtune->at_Positions[curtune->at_PosNr-1].pos_Transpose[chan]+1)&0xff );
8275                               curtune->at_PosNr++;
8276                               if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8277                               gui_render_posed( FALSE );
8278                               break;
8279 
8280                           }
8281                           break;
8282                       }
8283                       break;
8284 
8285                     case 13:
8286                       switch( curtune->at_editing )
8287                       {
8288                         case E_TRACK:
8289                           if( curtune->at_doing != D_EDITING ) break;
8290 
8291                           if( (curtune->at_tracked_curs%9) > 2 )
8292                           {
8293                             donkey = TRUE;
8294                             chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8295                             stp  = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr];
8296                             if( curtune->at_NoteNr > 0 )
8297                               pstp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_NoteNr-1];
8298                             else
8299                               pstp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[chan]&0xff][curtune->at_TrackLength-1];
8300 
8301                             if( (curtune->at_tracked_curs%9) < 6 )
8302                             {
8303                               modify_stp_w( curtune, stp, UNT_STP_FXANDPARAM, (pstp->stp_FX<<8)|pstp->stp_FXParam );
8304                             } else {
8305                               modify_stp_w( curtune, stp, UNT_STP_FXBANDPARAM, (pstp->stp_FXb<<8)|pstp->stp_FXbParam );
8306                             }
8307 
8308                             curtune->at_NoteNr += curtune->at_notejump;
8309                             curtune->at_modified = TRUE;
8310                             if( curtune->at_NoteNr >= curtune->at_TrackLength )
8311                               curtune->at_NoteNr = 0;
8312                             gui_render_tracker( FALSE );
8313                           }
8314                           break;
8315                         case E_POS:
8316                           if( curtune->at_PosNr == 0 ) break;
8317 
8318                           chan = curtune->at_posed_curs/5 + curtune->at_curlch;
8319 
8320                           donkey = TRUE;
8321 
8322                           switch( curtune->at_posed_curs%5 )
8323                           {
8324                             case 0:
8325                             case 1:
8326                             case 2:
8327                               modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, curtune->at_Positions[curtune->at_PosNr-1].pos_Track[chan] );
8328                               curtune->at_PosNr++;
8329                               if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8330                               gui_render_posed( FALSE );
8331                               break;
8332                             default:
8333                               modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRANS, curtune->at_Positions[curtune->at_PosNr-1].pos_Transpose[chan] );
8334                               curtune->at_PosNr++;
8335                               if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8336                               gui_render_posed( FALSE );
8337                               break;
8338 
8339                           }
8340                           break;
8341                       }
8342                       break;
8343 
8344 
8345                     case 70:
8346                       donkey = TRUE;
8347 
8348                       switch( curtune->at_editing )
8349                       {
8350                         case E_TRACK:
8351                           if( curtune->at_doing == D_IDLE ) break;
8352 
8353                           stp = &curtune->at_Tracks[curtune->at_Positions[curtune->at_PosNr].pos_Track[curtune->at_tracked_curs/9+curtune->at_curlch]&0xff][curtune->at_NoteNr];
8354 
8355                           switch( qual&(IEQUALIFIER_LSHIFT|IEQUALIFIER_LALT) )
8356                           {
8357                             case IEQUALIFIER_LSHIFT:
8358                               modify_stp_b( curtune, stp, UNT_STP_NOTE, 0 );
8359                               break;
8360                             case IEQUALIFIER_LALT:
8361                               modify_stp_b( curtune, stp, UNT_STP_INSTRUMENT, 0 );
8362                               break;
8363                             default:
8364                               modify_stp_w( curtune, stp, UNT_STP_NOTEANDINS, 0 );
8365                           }
8366                           curtune->at_NoteNr += curtune->at_notejump;
8367                           curtune->at_modified = TRUE;
8368                           if( curtune->at_NoteNr >= curtune->at_TrackLength )
8369                             curtune->at_NoteNr = 0;
8370                           gui_render_tracker( FALSE );
8371                           break;
8372                         case E_POS:
8373                           chan = curtune->at_posed_curs/5 + curtune->at_curlch;
8374 
8375                           if( ( curtune->at_posed_curs%5 ) < 3 )
8376                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRACK, 0 );
8377                           else
8378                             modify_pos_b( curtune, &curtune->at_Positions[curtune->at_PosNr], chan, UNT_POS_TRANS, 0 );
8379 
8380                           curtune->at_PosNr++;
8381                           if( curtune->at_PosNr == 1000 ) curtune->at_PosNr = 999;
8382                           gui_render_posed( FALSE );
8383                           break;
8384                       }
8385                       break;
8386 
8387                     case 76:
8388                       donkey = TRUE;
8389                       switch( curtune->at_editing )
8390                       {
8391                         case E_TRACK:
8392                           if( curtune->at_NoteNr > 0 )
8393                             curtune->at_NoteNr--;
8394                           else
8395                             curtune->at_NoteNr = curtune->at_TrackLength-1;
8396                           gui_render_tracked( FALSE );
8397                           break;
8398                         case E_POS:
8399                           if( curtune->at_PosNr > 0 )
8400                             curtune->at_PosNr--;
8401                           else
8402                             curtune->at_PosNr = 999;
8403                           gui_render_tracker( FALSE );
8404                           break;
8405                       }
8406                       break;
8407                     case 77:
8408                       donkey = TRUE;
8409                       switch( curtune->at_editing )
8410                       {
8411                         case E_TRACK:
8412                           if( curtune->at_NoteNr < curtune->at_TrackLength-1 )
8413                             curtune->at_NoteNr++;
8414                           else
8415                             curtune->at_NoteNr = 0;
8416                           gui_render_tracked( FALSE );
8417                           break;
8418                         case E_POS:
8419                           if( curtune->at_PosNr < 999 )
8420                             curtune->at_PosNr++;
8421                           else
8422                             curtune->at_PosNr = 0;
8423                           gui_render_tracker( FALSE );
8424                           break;
8425                       }
8426                       break;
8427                     case 85:
8428                     case 86:
8429                     case 87:
8430                     case 88:
8431                     case 89:
8432                       donkey = TRUE;
8433                       curtune->at_NoteNr = curtune->at_rempos[msg->Code-85];
8434                       if( curtune->at_NoteNr >= curtune->at_TrackLength )
8435                         curtune->at_NoteNr = curtune->at_TrackLength-1;
8436                       gui_render_tracker( FALSE );
8437                       break;
8438                   }
8439                   break;
8440                 case D_PLAYING:
8441                   switch( msg->Code )
8442                   {
8443                     case 76:
8444                       if( curtune->at_editing != E_POS ) break;
8445                       if( curtune->at_NextPosNr == -1 )
8446                         next = curtune->at_PosNr-1;
8447                       else
8448                         next = curtune->at_NextPosNr-1;
8449 
8450                       if( next < 0 ) next = 999;
8451                       curtune->at_NextPosNr = next;
8452                       gui_render_tracker( FALSE );
8453                       break;
8454 
8455                     case 77:
8456                       if( curtune->at_editing != E_POS ) break;
8457                       if( curtune->at_NextPosNr == -1 )
8458                         next = curtune->at_PosNr+1;
8459                       else
8460                         next = curtune->at_NextPosNr+1;
8461 
8462                       if( next > 999 ) next = 0;
8463                       curtune->at_NextPosNr = next;
8464                       gui_render_tracker( FALSE );
8465                       break;
8466                   }
8467                   break;
8468                 case D_RECORDING:
8469                   break;
8470               }
8471               break;
8472             case PN_INSED:
8473               if( curtune == NULL ) break;
8474 
8475               cins = &curtune->at_Instruments[curtune->at_curins];
8476               cple = &cins->ins_PList.pls_Entries[cins->ins_pcury];
8477 
8478               if( ( curtune->at_idoing == D_IDLE ) ||
8479                   ( ( curtune->at_idoing == D_EDITING ) && ( cins != NULL ) && ( cins->ins_pcurx == 0 ) ) )
8480               {
8481                 for( i=0; i<29; i++ )
8482                 {
8483                   if( ( msg->Code == pianokeys[i] ) ||
8484                       ( ( extrakeys[i] != -1 ) && ( msg->Code == extrakeys[i] ) ) )
8485                   {
8486                     donkey = TRUE;
8487                     if( curtune->at_idoing == D_IDLE )
8488                     {
8489                       chan = curtune->at_tracked_curs/9+curtune->at_curlch;
8490                       if( curtune->at_curins > 0 )
8491                         rp_play_note( curtune, curtune->at_curins, i+basekey+1, chan );
8492                     } else {
8493                       modify_ple_b( curtune, cins, cple, UNT_PLE_NOTE, i+basekey+1 );
8494                       cins->ins_pcury += curtune->at_inotejump;
8495                       gui_render_perf( curtune, cins, TRUE );
8496                     }
8497                     break;
8498                   }
8499                 }
8500               }
8501 
8502               if( ( curtune->at_idoing == D_EDITING ) &&
8503                   ( cple != NULL ) &&
8504                   ( cins->ins_pcurx > 0 ) )
8505               {
8506                 for( i=0; i<16; i++ )
8507                   if( msg->Code == hexkeys[i] )
8508                     break;
8509 
8510                 if( i<16 )
8511                 {
8512                   switch( cins->ins_pcurx )
8513                   {
8514                     case 1:
8515                       if( i < 5 )
8516                       {
8517                         donkey = TRUE;
8518                         modify_ple_b( curtune, cins, cple, UNT_PLE_WAVEFORM, i );
8519                         cins->ins_pcury += curtune->at_inotejump;
8520                         gui_render_perf( curtune, cins, TRUE );
8521                       }
8522                       break;
8523 
8524                     case 2:
8525                       donkey = TRUE;
8526                       modify_ple_b( curtune, cins, cple, UNT_PLE_FX0, i );
8527                       cins->ins_pcury += curtune->at_inotejump;
8528                       gui_render_perf( curtune, cins, TRUE );
8529                       break;
8530 
8531                     case 3:
8532                       donkey = TRUE;
8533                       modify_ple_b( curtune, cins, cple, UNT_PLE_FXPARAM0, (cple->ple_FXParam[0]&0xf)|(i<<4) );
8534                       cins->ins_pcury += curtune->at_inotejump;
8535                       gui_render_perf( curtune, cins, TRUE );
8536                       break;
8537 
8538                     case 4:
8539                       donkey = TRUE;
8540                       modify_ple_b( curtune, cins, cple, UNT_PLE_FXPARAM0, (cple->ple_FXParam[0]&0xf0)|i );
8541                       cins->ins_pcury += curtune->at_inotejump;
8542                       gui_render_perf( curtune, cins, TRUE );
8543                       break;
8544 
8545                     case 5:
8546                       donkey = TRUE;
8547                       modify_ple_b( curtune, cins, cple, UNT_PLE_FX1, i );
8548                       cins->ins_pcury += curtune->at_inotejump;
8549                       gui_render_perf( curtune, cins, TRUE );
8550                       break;
8551 
8552                     case 6:
8553                       donkey = TRUE;
8554                       modify_ple_b( curtune, cins, cple, UNT_PLE_FXPARAM1, (cple->ple_FXParam[1]&0xf)|(i<<4) );
8555                       cins->ins_pcury += curtune->at_inotejump;
8556                       gui_render_perf( curtune, cins, TRUE );
8557                       break;
8558 
8559                     case 7:
8560                       donkey = TRUE;
8561                       modify_ple_b( curtune, cins, cple, UNT_PLE_FXPARAM1, (cple->ple_FXParam[1]&0xf0)|i );
8562                       cins->ins_pcury += curtune->at_inotejump;
8563                       gui_render_perf( curtune, cins, TRUE );
8564                       break;
8565                   }
8566                 }
8567               }
8568 
8569               if( donkey ) break;
8570 
8571               switch( msg->Code )
8572               {
8573                 case 70:
8574                   donkey = TRUE;
8575                   if( cple )
8576                   {
8577                     modify_ple_b( curtune, cins, cple, UNT_PLE_NOTE, 0 );
8578                     cins->ins_pcury += curtune->at_inotejump;
8579                     gui_render_perf( curtune, cins, FALSE );
8580                   }
8581                   break;
8582                 case 68:
8583                   donkey = TRUE;
8584                   if( curtune->at_idoing != D_EDITING ) break;
8585 
8586                   if( cple )
8587                   {
8588                     modify_ple_w( curtune, cins, cple, UNT_PLE_FIXED, cple->ple_Fixed ^ 1 );
8589                     gui_render_perf( curtune, cins, TRUE );
8590                   }
8591                   break;
8592 
8593                 case 64:
8594                   donkey = TRUE;
8595                   curtune->at_doing = D_IDLE;
8596                   rp_stop();
8597                   gui_render_wavemeter();
8598 
8599                   if( curtune->at_idoing == D_IDLE )
8600                     curtune->at_idoing = D_EDITING;
8601                   else
8602                     curtune->at_idoing = D_IDLE;
8603 
8604                   gui_render_perf( curtune, cins, TRUE );
8605                   break;
8606 
8607                 case 76:
8608                   donkey = TRUE;
8609                   if( cins )
8610                   {
8611                     if( qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
8612                       cins->ins_pcury-=(PERF_H>>4);
8613                     else
8614                       cins->ins_pcury--;
8615 
8616                     gui_render_perf( curtune, cins, FALSE );
8617                   }
8618                   break;
8619 
8620                 case 77:
8621                   donkey = TRUE;
8622                   if( cins )
8623                   {
8624                     if( qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
8625                       cins->ins_pcury+=(PERF_H>>4);
8626                     else
8627                       cins->ins_pcury++;
8628                     gui_render_perf( curtune, cins, FALSE );
8629                   }
8630                   break;
8631 
8632                 case 79:
8633                   donkey = TRUE;
8634                   if( cins )
8635                   {
8636                     if( qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
8637                       cins->ins_pcurx = 0;
8638                     else
8639                       cins->ins_pcurx--;
8640                     gui_render_perf( curtune, cins, FALSE );
8641                   }
8642                   break;
8643 
8644                 case 78:
8645                   donkey = TRUE;
8646                   if( cins )
8647                   {
8648                     if( qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) )
8649                       cins->ins_pcurx = 7;
8650                     else
8651                       cins->ins_pcurx++;
8652                     gui_render_perf( curtune, cins, FALSE );
8653                   }
8654                   break;
8655               }
8656 
8657               break;
8658           }
8659 /*
8660           if( donkey == FALSE )
8661           {
8662             if( msg->Code < 128 )
8663               printf( "Key: %d (%d)\n", msg->Code, msg->Code|128 );
8664           } */
8665           break;
8666         case IDCMP_MOUSEBUTTONS:
8667           qual = msg->Qualifier;
8668           gui_mouse_handler( msg->MouseX, msg->MouseY, msg->Code );
8669           break;
8670       }
8671 #ifndef __SDL_WRAPPER__
8672       IExec->ReplyMsg( (struct Message *)msg );
8673 #endif
8674     }
8675   }
8676 
8677 #ifndef __SDL_WRAPPER__
8678   if( pref_dorestart )
8679   {
8680     if( !gui_restart() )
8681       quitting = TRUE;
8682     pref_dorestart = FALSE;
8683   }
8684 #endif
8685 }
8686 
gui_shutdown(void)8687 void gui_shutdown( void )
8688 {
8689   uint32 i;
8690 
8691   gui_close_prefs();
8692   if( gui_savethem ) gui_save_prefs();
8693 #ifndef __SDL_WRAPPER__
8694   if( mainwin ) IIntuition->CloseWindow( mainwin );
8695   if( scr )     IIntuition->CloseScreen( scr );
8696 #endif
8697 
8698   if( cbpbuf ) IExec->FreeVec( cbpbuf );
8699 
8700 #ifndef __SDL_WRAPPER__
8701   if( ins_lreq ) IAsl->FreeAslRequest( ins_lreq );
8702   if( ins_sreq ) IAsl->FreeAslRequest( ins_sreq );
8703   if( sng_lreq ) IAsl->FreeAslRequest( sng_lreq );
8704   if( sng_sreq ) IAsl->FreeAslRequest( sng_sreq );
8705   if( dir_req )  IAsl->FreeAslRequest( dir_req );
8706 
8707   for( i=0; i<BM_END; i++ ) if( bitmaps[i].bm ) IGraphics->FreeBitMap( bitmaps[i].bm );
8708   for( i=0; i<TB_END; i++ ) if( tbx[i].bm.bm )  IGraphics->FreeBitMap( tbx[i].bm.bm );
8709 
8710   if( prpfont ) IGraphics->CloseFont( prpfont );
8711   if( fixfont ) IGraphics->CloseFont( fixfont );
8712   if( sfxfont ) IGraphics->CloseFont( sfxfont );
8713 
8714   if( gui_tick_signum != -1 ) IExec->FreeSignal( gui_tick_signum );
8715 
8716   if( IRequester )    IExec->DropInterface( (struct Interface *)IRequester );
8717   if( RequesterBase ) IExec->CloseLibrary( RequesterBase );
8718   if( IKeymap )       IExec->DropInterface( (struct Interface *)IKeymap );
8719   if( KeymapBase )    IExec->CloseLibrary( KeymapBase );
8720   if( IDiskfont )     IExec->DropInterface( (struct Interface *)IDiskfont );
8721   if( DiskfontBase )  IExec->CloseLibrary( DiskfontBase );
8722   if( IDataTypes )    IExec->DropInterface( (struct Interface *)IDataTypes );
8723   if( DataTypesBase ) IExec->CloseLibrary( DataTypesBase );
8724   if( IP96)           IExec->DropInterface( (struct Interface *)IP96 );
8725   if( GfxBase )       IExec->CloseLibrary( P96Base );
8726   if( IGraphics )     IExec->DropInterface( (struct Interface *)IGraphics );
8727   if( GfxBase )       IExec->CloseLibrary( GfxBase );
8728   if( IIntuition )    IExec->DropInterface( (struct Interface *)IIntuition );
8729   if( IntuitionBase ) IExec->CloseLibrary( IntuitionBase );
8730 #else
8731   for( i=0; i<BM_END; i++ ) if( bitmaps[i].srf ) SDL_FreeSurface( bitmaps[i].srf );
8732   for( i=0; i<TB_END; i++ ) if( tbx[i].bm.srf )  SDL_FreeSurface( tbx[i].bm.srf );
8733   if( prefbm.srf ) SDL_FreeSurface( prefbm.srf );
8734   TTF_CloseFont( prpttf ); prpttf = NULL;
8735   TTF_CloseFont( fixttf ); fixttf = NULL;
8736   TTF_CloseFont( sfxttf ); sfxttf = NULL;
8737 #endif
8738 }
8739 
8740