Initial commit.
[amiga/xmodule.git] / SampleWin.c
1 /*
2 **      SampleWin.c
3 **
4 **      Copyright (C) 1994,95,96 Bernardo Innocenti
5 **
6 **      Sample editor handling functions.
7 */
8
9 #include <intuition/intuition.h>
10 #include <intuition/gadgetclass.h>
11 #include <libraries/gadtools.h>
12 #include <graphics/rpattr.h>
13 #include <graphics/gfxmacros.h>
14
15 #include <clib/exec_protos.h>
16 #include <clib/intuition_protos.h>
17 #include <clib/graphics_protos.h>
18 #include <clib/gadtools_protos.h>
19 #include <clib/xmodule_protos.h>
20
21 #include <pragmas/exec_sysbase_pragmas.h>
22 #include <pragmas/intuition_pragmas.h>
23 #include <pragmas/gadtools_pragmas.h>
24 #include <pragmas/graphics_pragmas.h>
25 #include <pragmas/xmodule_pragmas.h>
26
27 #include "XModulePriv.h"
28 #include "Gui.h"
29
30
31
32 /* Gadgets IDs */
33
34 enum {
35         GD_SampScroll,
36         GD_SampZoomIn,
37         GD_SampRangeAll,
38         GD_SampShowRange,
39         GD_SampZoomOut,
40         GD_SampClearRange,
41         GD_SampShowAll,
42         GD_SampSize,
43         GD_SampPlayR,
44         GD_SampPlayD,
45         GD_SampPlayL,
46         GD_SampPlayA,
47         GD_DisplayStart,
48         GD_DisplayEnd,
49         GD_DisplayLen,
50         GD_RangeStart,
51         GD_RangeEnd,
52         GD_RangeLen,
53         GD_RepStart,
54         GD_RepEnd,
55         GD_RepLen,
56         GD_SampBox,
57
58         Sample_CNT
59 };
60
61
62 /* Sample rendering modes */
63
64 enum {
65         SAMP_PIXEL,
66         SAMP_LINE,
67         SAMP_FILLED
68 };
69
70
71 /* Local functions prototypes */
72
73 static void SampleRender        (struct WinUserData *wud);
74 static LONG SampBoxSetup        (struct Gadget *g);
75 static void HandleSampleIDCMP (void);
76 static void DrawRange           (void);
77 static void UpdateRange         (WORD newend);
78 static void UpdateRangeInfo     (void);
79
80 static void DrawPixelGraph (struct RastPort *rp, BYTE *samp,
81         UWORD xmin, UWORD xmax, UWORD ycoord, UWORD height, UWORD step);
82 static void DrawLineGraph (struct RastPort *rp, BYTE *samp,
83         UWORD xmin, UWORD xmax, UWORD ycoord, UWORD height, UWORD step);
84 static void DrawFilledGraph (struct RastPort *rp, BYTE *samp,
85         UWORD xmin, UWORD xmax, UWORD ycoord, UWORD height, UWORD step);
86
87 static void SampScrollClicked (void);
88 static void SampZoomInClicked (void);
89 static void SampRangeAllClicked (void);
90 static void SampShowRangeClicked (void);
91 static void SampZoomOutClicked (void);
92 static void SampClearRangeClicked (void);
93 static void SampShowAllClicked (void);
94 static void SampPlayRClicked (void);
95 static void SampPlayDClicked (void);
96 static void SampPlayLClicked (void);
97 static void SampPlayAClicked (void);
98 static void DisplayStartClicked (void);
99 static void DisplayEndClicked (void);
100 static void DisplayLenClicked (void);
101 static void RangeStartClicked (void);
102 static void RangeEndClicked (void);
103 static void RangeLenClicked (void);
104 static void RepStartClicked (void);
105 static void RepLenClicked (void);
106 static void RepEndClicked (void);
107 static void SampBoxClicked (void);
108
109 static void SampleMiCut (void);
110 static void SampleMiCopy (void);
111 static void SampleMiPaste (void);
112 static void SampleMiPoints (void);
113 static void SampleMiLines (void);
114 static void SampleMiFilled (void);
115
116
117 static struct IBox SampBox;             /* Sample Box Coordinates */
118 static WORD             RangeStartX, RangeEndX, RangePole;
119 static WORD             LoopPole1, LoopPole2;
120 static LONG             DisplayStart, DisplayEnd;
121
122
123
124 static struct Gadget    *SampleGadgets[Sample_CNT];
125
126 static struct NewMenu SampleNewMenu[] = {
127         NM_TITLE, (STRPTR)MSG_EDIT_MEN, NULL, 0, NULL, NULL,
128         NM_ITEM, (STRPTR)MSG_CUT_MEN, (STRPTR)"X", 0, 0L, (APTR)SampleMiCut,
129         NM_ITEM, (STRPTR)MSG_COPY_MEN, (STRPTR)"C", 0, 0L, (APTR)SampleMiCopy,
130         NM_ITEM, (STRPTR)MSG_PASTE_MEN, (STRPTR)"V", 0, 0L, (APTR)SampleMiPaste,
131         NM_TITLE, (STRPTR)MSG_RENDER_MEN, NULL, 0, NULL, NULL,
132         NM_ITEM, (STRPTR)MSG_POINTS_MEN, NULL, CHECKIT, 6L, (APTR)SampleMiPoints,
133         NM_ITEM, (STRPTR)MSG_LINES_MEN, NULL, CHECKIT|CHECKED, 5L, (APTR)SampleMiLines,
134         NM_ITEM, (STRPTR)MSG_FILLED_MEN, NULL, CHECKIT, 3L, (APTR)SampleMiFilled,
135         NM_END, NULL, NULL, 0, 0L, NULL
136 };
137
138 static UWORD SampleGTypes[] = {
139         SCROLLER_KIND,
140         BUTTON_KIND,
141         BUTTON_KIND,
142         BUTTON_KIND,
143         BUTTON_KIND,
144         BUTTON_KIND,
145         BUTTON_KIND,
146         NUMBER_KIND,
147         BUTTON_KIND,
148         BUTTON_KIND,
149         BUTTON_KIND,
150         BUTTON_KIND,
151         INTEGER_KIND,
152         INTEGER_KIND,
153         INTEGER_KIND,
154         INTEGER_KIND,
155         INTEGER_KIND,
156         INTEGER_KIND,
157         INTEGER_KIND,
158         INTEGER_KIND,
159         INTEGER_KIND,
160         GENERIC_KIND
161 };
162
163 struct NewGadget SampleNGad[] = {
164         4, 154, 623, 8, NULL, NULL, GD_SampScroll, 0, NULL, (APTR)SampScrollClicked,
165         4, 1, 105, 12, (UBYTE *)"Zoom _In", NULL, GD_SampZoomIn, PLACETEXT_IN, NULL, (APTR)SampZoomInClicked,
166         112, 1, 105, 12, (UBYTE *)"Range _All", NULL, GD_SampRangeAll, PLACETEXT_IN, NULL, (APTR)SampRangeAllClicked,
167         112, 27, 105, 12, (UBYTE *)"Show Range", NULL, GD_SampShowRange, PLACETEXT_IN, NULL, (APTR)SampShowRangeClicked,
168         4, 14, 105, 12, (UBYTE *)"Zoom _Out", NULL, GD_SampZoomOut, PLACETEXT_IN, NULL, (APTR)SampZoomOutClicked,
169         112, 14, 105, 12, (UBYTE *)"_Clear Range", NULL, GD_SampClearRange, PLACETEXT_IN, NULL, (APTR)SampClearRangeClicked,
170         4, 27, 105, 12, (UBYTE *)"Show All", NULL, GD_SampShowAll, PLACETEXT_IN, NULL, (APTR)SampShowAllClicked,
171         112, 40, 105, 12, (UBYTE *)"Sample Size", NULL, GD_SampSize, PLACETEXT_LEFT, NULL, NULL,
172         220, 27, 105, 12, (UBYTE *)"Play Range", NULL, GD_SampPlayR, PLACETEXT_IN, NULL, (APTR)SampPlayRClicked,
173         220, 1, 105, 12, (UBYTE *)"Play Display", NULL, GD_SampPlayD, PLACETEXT_IN, NULL, (APTR)SampPlayDClicked,
174         220, 40, 105, 12, (UBYTE *)"Loop Play", NULL, GD_SampPlayL, PLACETEXT_IN, NULL, (APTR)SampPlayLClicked,
175         220, 14, 105, 12, (UBYTE *)"Play All", NULL, GD_SampPlayA, PLACETEXT_IN, NULL, (APTR)SampPlayAClicked,
176         414, 11, 69, 13, (UBYTE *)"_Display", NULL, GD_DisplayStart, PLACETEXT_LEFT, NULL, (APTR)DisplayStartClicked,
177         486, 11, 69, 13, NULL, NULL, GD_DisplayEnd, 0, NULL, (APTR)DisplayEndClicked,
178         558, 11, 69, 13, NULL, NULL, GD_DisplayLen, 0, NULL, (APTR)DisplayLenClicked,
179         414, 25, 69, 13, (UBYTE *)"_Range", NULL, GD_RangeStart, PLACETEXT_LEFT, NULL, (APTR)RangeStartClicked,
180         486, 25, 69, 13, NULL, NULL, GD_RangeEnd, 0, NULL, (APTR)RangeEndClicked,
181         558, 25, 69, 13, NULL, NULL, GD_RangeLen, 0, NULL, (APTR)RangeLenClicked,
182         414, 39, 69, 13, (UBYTE *)"R_epeat", NULL, GD_RepStart, PLACETEXT_LEFT, NULL, (APTR)RepStartClicked,
183         486, 39, 69, 13, NULL, NULL, GD_RepEnd, 0, NULL, (APTR)RepEndClicked,
184         558, 39, 69, 13, NULL, NULL, GD_RepLen, 0, NULL, (APTR)RepLenClicked,
185         0, 0, 0, 0, NULL, NULL, GD_SampBox, 0, NULL, (APTR)SampBoxClicked
186 };
187
188 static static ULONG SampleGTags[] = {
189         PGA_Freedom, LORIENT_HORIZ, GA_RelVerify, TRUE, TAG_DONE,
190         TAG_DONE,
191         TAG_DONE,
192         TAG_DONE,
193         TAG_DONE,
194         TAG_DONE,
195         TAG_DONE,
196         GTNM_Border, TRUE, TAG_DONE,
197         TAG_DONE,
198         TAG_DONE,
199         TAG_DONE,
200         TAG_DONE,
201         GTIN_MaxChars, 6, TAG_DONE,
202         GTIN_MaxChars, 6, TAG_DONE,
203         GTIN_MaxChars, 6, TAG_DONE,
204         GTIN_MaxChars, 6, TAG_DONE,
205         GTIN_MaxChars, 6, TAG_DONE,
206         GTIN_MaxChars, 6, TAG_DONE,
207         GTIN_MaxChars, 6, TAG_DONE,
208         GTIN_MaxChars, 6, TAG_DONE,
209         GTIN_MaxChars, 6, TAG_DONE,
210         XMGAD_SetupFunc, (ULONG)SampBoxSetup, TAG_DONE
211 };
212
213
214 static struct IntuiText SampleIText[] = {
215         1, 0, JAM1,445, 5, NULL, (UBYTE *)"Start", NULL,
216         1, 0, JAM1,516, 5, NULL, (UBYTE *)"End", NULL,
217         1, 0, JAM1,589, 5, NULL, (UBYTE *)"Length", NULL };
218
219 #define Sample_TNUM 3
220
221
222
223 struct WinUserData SampleWUD =
224 {
225         { NULL, NULL },
226         NULL,
227         SampleGadgets,
228         NULL,
229         NULL,
230         NULL,
231         { 0, 0, 0, 0 },
232         { 0, 0, 0, 0 },
233         0,
234
235         CloseSampleWindow,
236         NULL,
237         HandleSampleIDCMP,
238
239         SampleNewMenu,
240         NULL,
241         Sample_CNT,
242         WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_ACTIVATE,
243         SCROLLERIDCMP|ARROWIDCMP|BUTTONIDCMP|INTEGERIDCMP|IDCMP_MENUPICK|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_MOUSEMOVE,
244         (STRPTR)MSG_SAMPLE_TITLE,
245         NULL,
246         NULL,
247         NULL
248 };
249
250
251
252 static void SampleRender (struct WinUserData *wud)
253 {
254 /*      DrawBevelBox (wud->Win->RPort, SampBox.Left - 2, SampBox.Top - 1,
255                                         SampBox.Width + 4, SampBox.Height + 2,
256                                         GT_VisualInfo, VisualInfo,
257                                         GTBB_Recessed, TRUE,
258                                         TAG_DONE );
259
260         RenderWindowTexts (wud, SampleIText, Sample_TNUM);
261 */
262         UpdateSampGraph();
263         UpdateSampInfo();
264 }
265
266
267
268 GLOBALCALL LONG OpenSampleWindow (void)
269 {
270         struct Window *win;
271         struct SongInfo *si;
272
273         DisplayStart = RangeStartX = RangeEndX = 0;
274
275         if (si = xmLockActiveSong (SM_SHARED))
276         {
277                 DisplayEnd = si->Instr[si->CurrentInst]->Length - 1;
278                 ReleaseSemaphore (&si->Lock);
279         }
280         else
281                 DisplayEnd = 0;
282
283         if (DisplayEnd < 0) DisplayEnd = 0;
284         LoopPole1 = LoopPole2 = 0;
285
286         win = MyOpenWindow (&SampleWUD);
287
288         UpdateSampleMenu();
289
290         return (!win);
291 }
292
293
294
295 GLOBALCALL void CloseSampleWindow (void)
296 {
297         MyCloseWindow (SampleWUD.Win);
298 }
299
300
301
302 static LONG SampBoxSetup (struct Gadget *g)
303 {
304         /**/
305         SampBox.Left    = OffX; // + ComputeX (&SampleWUD, 4) + 2;
306         SampBox.Top             = OffY; // + ComputeY (&SampleWUD, 53) + 1;
307         SampBox.Width   = 500;//ComputeX (&SampleWUD, 622) - 4;
308         SampBox.Height  = 300;//ComputeY (&SampleWUD, 100) - 2;
309
310         g->LeftEdge = SampBox.Left;
311         g->TopEdge = SampBox.Top;
312         g->Width = SampBox.Width;
313         g->Height = SampBox.Height;
314
315         g->Flags                |= GFLG_GADGHNONE;
316         g->Activation   |= GACT_IMMEDIATE | GACT_FOLLOWMOUSE | GACT_RELVERIFY;
317         g->GadgetType   |= GTYP_BOOLGADGET;     /* Preserve GadTools special flags */
318
319         return RETURN_OK;
320 }
321
322
323
324 static void HandleSampleIDCMP (void)
325 {
326         WORD mousex; //, mousey;
327
328         if (IntuiMsg.Class != IDCMP_MOUSEMOVE)
329                 return;
330
331         mousex = IntuiMsg.MouseX - SampBox.Left;
332 //      mousey = IntuiMsg.MouseY - SampBox.Top;
333
334         /* Clip mouse position */
335         if (mousex < 0) mousex = 0;
336 //      if (mousey < 0) mousey = 0;
337         if (mousex >= SampBox.Width) mousex = SampBox.Width - 1;
338 //      if (mousey >= SampBox.Height) mousey = SampBox.Height - 1;
339
340         if (mousex == RangeEndX) /* Do not redraw until mouse position has changed */
341                 return;
342
343         UpdateRange (mousex);
344 }
345
346
347 /********************/
348 /* Sample Functions */
349 /********************/
350
351 static void DrawPixelGraph (struct RastPort *rp, BYTE *samp,
352         UWORD xmin, UWORD xmax, UWORD ycoord, UWORD height, UWORD step)
353 {
354         ULONG i;
355         UWORD x;
356
357         for (i = 0, x = xmin ; x < xmax ; i += step, x++)
358                 WritePixel (rp, x, (samp[i]*height) >> 8 + ycoord);
359 }
360
361
362
363 static void DrawLineGraph (struct RastPort *rp, BYTE *samp,
364         UWORD xmin, UWORD xmax, UWORD ycoord, UWORD height, UWORD step)
365 {
366         ULONG i;
367         UWORD x;
368
369         Move (rp, xmin, ycoord);
370
371         for (i = 0, x = xmin ; x < xmax ; i += step, x++)
372                 Draw (rp, x, (samp[i]*height)/256 + ycoord);
373 }
374
375
376
377 static void DrawFilledGraph (struct RastPort *rp, BYTE *samp,
378         UWORD xmin, UWORD xmax, UWORD ycoord, UWORD height, UWORD step)
379 {
380         UWORD x;
381         ULONG i;
382
383         for (i = 0, x = xmin ; x < xmax ; i += step, x++)
384         {
385                 Move (rp, x, ycoord);
386                 Draw (rp, x, (samp[i]*height)/256 + ycoord);
387         }
388 }
389
390
391
392 GLOBALCALL void UpdateSample (void)
393
394 /* You call this function when the selected instrument has changed. */
395 {
396         struct SongInfo *si;
397
398         if (SampleWUD.Win)
399         {
400                 if (si = xmLockActiveSong (SM_SHARED))
401                 {
402                         DisplayStart = RangeStartX = RangeEndX = DisplayEnd = 0;
403
404                         if (si->CurrentInst)
405                                 DisplayEnd = si->Instr[si->CurrentInst]->Length - 1;
406
407                         if (DisplayEnd < 0) DisplayEnd = 0;
408
409                         UpdateSampGraph();
410                         UpdateSampInfo();
411
412                         ReleaseSemaphore (&si->Lock);
413                 }
414         }
415 }
416
417
418
419 GLOBALCALL void UpdateSampleMenu (void)
420 {
421         if (SampleWUD.Win)
422         {
423                 struct Menu *menu = SampleWUD.Win->MenuStrip;
424                 struct MenuItem *item = menu->NextMenu->FirstItem;
425
426                 ClearMenuStrip (SampleWUD.Win);
427
428
429                 /* Clear checkmarks */
430
431                 item->Flags &= ~CHECKED;
432                 item->NextItem->Flags &= ~CHECKED;
433                 item->NextItem->NextItem->Flags &= ~CHECKED;
434
435
436                 /* Set checkmark */
437
438                 switch (GuiSwitches.SampDrawMode)
439                 {
440                         case SAMP_PIXEL:
441                                 item->Flags |= CHECKED;
442                                 break;
443
444                         case SAMP_LINE:
445                                 item->NextItem->Flags |= CHECKED;
446                                 break;
447
448                         case SAMP_FILLED:
449                                 item->NextItem->NextItem->Flags |= CHECKED;
450                                 break;
451                 }
452
453                 ResetMenuStrip (SampleWUD.Win, menu);
454         }
455 }
456
457
458
459 GLOBALCALL void UpdateSampInfo (void)
460 {
461         struct SongInfo *si;
462
463         if (!SampleWUD.Win)     return;
464
465         if (si = xmLockActiveSong (SM_SHARED))
466         {
467                 struct Instrument *instr = si->Instr[si->CurrentInst];
468                 LONG repend;
469
470                 repend = instr->Repeat + instr->Replen - 1;
471                 if (repend < 0) repend = 0;
472
473                 SetGadgets (&SampleWUD,
474                         GD_RepStart,            instr->Repeat,
475                         GD_RepEnd,                      repend,
476                         GD_RepLen,                      instr->Replen,
477                         GD_SampSize,            instr->Length,
478                         GD_DisplayStart,        DisplayStart,
479                         GD_DisplayEnd,          DisplayEnd,
480                         GD_DisplayLen,          DisplayEnd ? (DisplayEnd - DisplayStart + 1) : 0,
481                         -1);
482
483                 /* Loop markers */
484                 {
485                         struct RastPort *rp = SampleWUD.Win->RPort;
486
487                         SetDrMd (rp, COMPLEMENT);
488                         SetDrPt (rp, 0xFF00);
489
490                         /* Delete previous loop */
491                         if (LoopPole1)
492                         {
493                                 Move (rp, LoopPole1, SampBox.Top);
494                                 Draw (rp, LoopPole1, SampBox.Top + SampBox.Height);
495                                 LoopPole1 = 0;
496                         }
497                         if (LoopPole2)
498                         {
499                                 Move (rp, LoopPole2, SampBox.Top);
500                                 Draw (rp, LoopPole2, SampBox.Top + SampBox.Height);
501                                 LoopPole2 = 0;
502                         }
503
504                         if (instr->Replen) /* Draw new loop */
505                         {
506                                 if (DisplayStart <= instr->Repeat && instr->Repeat <= DisplayEnd)
507                                 {
508                                         LoopPole1 = SampBox.Left + ((SampBox.Width * (instr->Repeat - DisplayStart)) / (DisplayEnd - DisplayStart + 1));
509
510                                         Move (rp, LoopPole1, SampBox.Top);
511                                         Draw (rp, LoopPole1, SampBox.Top + SampBox.Height - 1);
512                                 }
513
514                                 if (DisplayStart <= repend && repend <= DisplayEnd+1)
515                                 {
516                                         LoopPole2 = SampBox.Left + ((SampBox.Width * (repend - DisplayStart)) / (DisplayEnd - DisplayStart + 1));
517
518                                         Move (rp, LoopPole2, SampBox.Top);
519                                         Draw (rp, LoopPole2, SampBox.Top + SampBox.Height - 1);
520                                 }
521                         }
522
523                         SetDrPt (rp, 0xFFFF);
524                 }
525
526                 ReleaseSemaphore (&si->Lock);
527         }
528 }
529
530
531
532 static void UpdateRangeInfo (void)
533 {
534         WORD    rs = DisplayStart + RangeStartX,
535                         re = DisplayStart + RangeEndX;
536
537         if (!SampleWUD.Win) return;
538
539         SetGadgets (&SampleWUD,
540                 GD_RangeStart,          rs,
541                 GD_RangeEnd,            re,
542                 GD_RangeLen,            abs(re - rs),
543                 -1);
544 }
545
546
547
548 GLOBALCALL void UpdateSampGraph (void)
549 {
550         struct SongInfo *si;
551         struct RastPort *rp;
552         BYTE *samp;
553         ULONG maxpen;
554         UWORD step, xmin, xmax, height, ycoord;
555
556         if (!SampleWUD.Win) return;
557
558
559         if (si = xmLockActiveSong (SM_SHARED))
560         {
561                 rp = SampleWUD.Win->RPort;
562                 samp = si->Instr[si->CurrentInst]->Sample;
563
564                 xmin    = SampBox.Left;
565                 xmax    = xmin + SampBox.Width;
566                 height  = SampBox.Height;
567                 ycoord  = SampBox.Top + height/2;
568                 step    = si->Instr[si->CurrentInst]->Length / SampBox.Width;
569
570                 /* This helps with samples smaller than the graphic x size */
571                 if (step == 0) step = 1;
572
573                 /* Clear instrument rectangle */
574
575                 SetDrMd (rp, JAM1);
576                 SetAPen (rp, DrawInfo->dri_Pens[BACKGROUNDPEN]);
577                 RectFill (rp, SampBox.Left, SampBox.Top,
578                         SampBox.Left + SampBox.Width - 1, SampBox.Top + SampBox.Height - 1);
579                 LoopPole1 = LoopPole2 = 0;
580
581
582                 if (GfxBase->lib_Version >= 39) /* Optimized drawing with V39 */
583                 {
584                         GetRPAttrs (rp,
585                                 RPTAG_MaxPen, &maxpen,
586                                 TAG_DONE);
587                         SetMaxPen (rp, max(DrawInfo->dri_Pens[TEXTPEN], DrawInfo->dri_Pens[FILLPEN]));
588                 }
589
590                 /* Draw mid line */
591                 SetAPen (rp, DrawInfo->dri_Pens[TEXTPEN]);
592                 Move (rp, xmin, ycoord);
593                 Draw (rp, xmax-1, ycoord);
594
595                 /* Draw sample graphic */
596
597                 if (samp)
598                 {
599                         switch (GuiSwitches.SampDrawMode)
600                         {
601                                 case SAMP_PIXEL:
602                                         DrawPixelGraph (rp, samp, xmin, xmax, ycoord, height, step);
603                                         break;
604
605                                 case SAMP_LINE:
606                                         DrawLineGraph (rp, samp, xmin, xmax, ycoord, height, step);
607                                         break;
608
609                                 case SAMP_FILLED:
610                                         DrawFilledGraph (rp, samp, xmin, xmax, ycoord, height, step);
611                                         break;
612                         }
613                 }
614
615                 DrawRange();    /* Redraw range */
616
617                 /* Restore MaxPen if appropriate */
618                 if (GfxBase->lib_Version >= 39) SetMaxPen (rp, maxpen);
619
620                 ReleaseSemaphore (&si->Lock);
621         }
622 }
623
624
625
626 static void DrawRange (void)
627 {
628         ULONG maxpen;
629         WORD xmin, xmax;
630         struct RastPort *rp = SampleWUD.Win->RPort;
631
632         if (RangeStartX > RangeEndX)
633         {
634                 xmin = RangeEndX;
635                 xmax = RangeStartX;
636         }
637         else
638         {
639                 xmin = RangeStartX;
640                 xmax = RangeEndX;
641         }
642
643         /* Optimized drawing for V39 */
644
645         if (GfxBase->lib_Version >= 39)
646         {
647                 GetRPAttrs (rp,
648                         RPTAG_MaxPen, &maxpen,
649                         TAG_DONE);
650                 SetMaxPen (rp, max(DrawInfo->dri_Pens[TEXTPEN], DrawInfo->dri_Pens[FILLPEN]));
651         }
652
653         SetDrMd (rp, COMPLEMENT);
654         RectFill (rp, SampBox.Left + xmin, SampBox.Top,
655                 SampBox.Left + xmax, SampBox.Top + SampBox.Height - 1);
656
657         /* Restore MaxPen if appropriate */
658         if (GfxBase->lib_Version >= 39) SetMaxPen (rp, maxpen);
659 }
660
661
662 static void UpdateRange (WORD newend)
663
664 /* Optimized range offset drawing */
665 {
666         WORD pole = RangeStartX;        /* The fixed end of the range */
667
668         RangeStartX = RangeEndX;
669         RangeEndX = newend;
670
671         if (RangeEndX < pole  && RangeStartX <= pole)           /* Range _left_ of pole */
672         {
673                 if (RangeStartX > RangeEndX) RangeStartX--;             /* Grow range   */
674                 else if (RangeStartX < RangeEndX) RangeEndX--;  /* Reduce range */
675                 DrawRange();                                                                    /* Draw/clear offset area */
676
677         }
678         else if (RangeEndX > pole && RangeStartX >= pole)       /* Range _right_ of pole */
679         {
680                 if (RangeStartX < RangeEndX) RangeStartX++;             /* Grow range   */
681                 else if (RangeStartX > RangeEndX) RangeEndX++;  /* Reduce range */
682                 DrawRange();                                                                    /* Draw/clear offset area */
683         }
684         else    /* Mouse has crossed the pole: it must be redrawn */
685         {
686                 DrawRange();
687                 RangeStartX = RangeEndX = pole;
688                 DrawRange();
689         }
690
691         RangeStartX = pole;
692         RangeEndX = newend;
693         UpdateRangeInfo();
694 }
695
696
697
698 /******************/
699 /* Sample Gadgets */
700 /******************/
701
702 static void SampScrollClicked (void)
703 {
704 }
705
706
707
708 static void SampZoomInClicked (void)
709 {
710 }
711
712
713
714 static void SampRangeAllClicked (void)
715 {
716         DrawRange();    /* Delete previous range */
717         RangeStartX = 0;
718         RangeEndX = SampBox.Width;
719         DrawRange();
720         UpdateRangeInfo();
721 }
722
723
724
725 static void SampShowRangeClicked (void)
726 {
727 }
728
729
730
731 static void SampZoomOutClicked (void)
732 {
733 }
734
735
736
737 static void SampClearRangeClicked (void)
738 {
739         if (RangeStartX == RangeEndX) return;
740
741         DrawRange();
742         RangeStartX = RangeEndX = 0;
743         DrawRange();
744         UpdateRangeInfo();
745 }
746
747
748
749 static void SampShowAllClicked (void)
750 {
751         struct SongInfo *si;
752
753         DisplayStart = 0;
754
755         if (si = xmLockActiveSong (SM_SHARED))
756         {
757                 DisplayEnd = si->Instr[si->CurrentInst]->Length - 1;
758                 ReleaseSemaphore (&si->Lock);
759         }
760         else
761                 DisplayEnd = 0;
762         UpdateSampGraph();
763         UpdateSampInfo();
764 }
765
766
767
768 static void SampPlayRClicked (void)
769 {
770 }
771
772 static void SampPlayDClicked (void)
773 {
774 }
775
776 static void SampPlayLClicked (void)
777 {
778 }
779
780 static void SampPlayAClicked (void)
781 {
782         struct SongInfo *si;
783
784         if (si = xmLockActiveSong (SM_SHARED))
785         {
786                 struct Instrument *instr = si->Instr[si->CurrentInst];
787
788                 PlaySample (instr->Sample, instr->Length, instr->Volume, 0x1AC);        /**/
789                 ReleaseSemaphore (&si->Lock);
790         }
791 }
792
793 static void DisplayStartClicked (void)
794 {
795 }
796
797 static void DisplayEndClicked (void)
798 {
799 }
800
801 static void DisplayLenClicked (void)
802 {
803 }
804
805 static void RangeStartClicked (void)
806 {
807 }
808
809 static void RangeEndClicked (void)
810 {
811 }
812
813 static void RangeLenClicked (void)
814 {
815 }
816
817
818
819 static void RepStartClicked (void)
820 {
821         struct SongInfo *si;
822
823         if (si = xmLockActiveSong (SM_SHARED))
824         {
825                 struct Instrument *instr = si->Instr[si->CurrentInst];
826
827                 instr->Repeat = GetNumber (SampleGadgets[GD_RepStart]);
828
829                 if (instr->Repeat & 1) instr->Repeat--;
830
831                 if (instr->Repeat >= instr->Length)
832                         instr->Repeat = instr->Length - 2;
833
834                 if (((LONG)instr->Repeat) < 0)
835                         instr->Repeat = 0;
836
837                 if (instr->Repeat + instr->Replen > instr->Length - 2)
838                         instr->Replen = instr->Length - instr->Repeat;
839
840                 if (((LONG)instr->Replen) < 0)
841                         instr->Replen = 0;
842
843                 ReleaseSemaphore (&si->Lock);
844         }
845
846         UpdateSampInfo();
847 }
848
849
850
851 static void RepLenClicked (void)
852 {
853         struct SongInfo *si;
854
855         if (si = xmLockActiveSong (SM_SHARED))
856         {
857                 struct Instrument *instr = si->Instr[si->CurrentInst];
858
859                 instr->Replen = GetNumber (SampleGadgets[GD_RepLen]);
860
861                 if (instr->Replen & 1) instr->Replen++;
862
863                 if (instr->Replen + instr->Repeat >= instr->Length)
864                         instr->Replen = instr->Length - instr->Repeat;
865
866                 if (((LONG)instr->Replen) < 0)
867                         instr->Replen = 0;
868
869                 ReleaseSemaphore (&si->Lock);
870         }
871
872         UpdateSampInfo();
873 }
874
875
876
877 static void RepEndClicked (void)
878 {
879         struct SongInfo *si;
880
881         if (si = xmLockActiveSong (SM_SHARED))
882         {
883                 struct Instrument *instr = si->Instr[si->CurrentInst];
884
885                 instr->Replen = GetNumber (SampleGadgets[GD_RepEnd]) - instr->Repeat;
886
887                 if (instr->Replen & 1) instr->Replen++;
888
889                 if (instr->Replen + instr->Repeat >= instr->Length)
890                         instr->Replen = instr->Length - instr->Repeat;
891
892                 if (((LONG)instr->Replen) < 0) instr->Replen = 0;
893
894                 ReleaseSemaphore (&si->Lock);
895         }
896
897         UpdateSampInfo();
898 }
899
900
901
902 static void SampBoxClicked (void)
903 {
904         if (IntuiMsg.Class == IDCMP_GADGETDOWN)
905         {
906                 DrawRange(); /* Clear old range */
907                 RangePole = RangeStartX = RangeEndX = IntuiMsg.MouseX - SampBox.Left;
908                 DrawRange(); /* Draw pole */
909                 UpdateRangeInfo();
910
911                 //SetPointer (SampleWUD.Win, BlockPointer, 16, 16, -8, -7);
912         }
913         else if (IntuiMsg.Class == IDCMP_GADGETUP)
914                 ;       //ClearPointer (SampleWUD.Win);
915 }
916
917
918 /****************/
919 /* Sample Menus */
920 /****************/
921
922 static void SampleMiCut (void)
923 {
924         /* routine when (sub)item "Cut" is selected. */
925 }
926
927 static void SampleMiCopy (void)
928 {
929         /* routine when (sub)item "Copy" is selected. */
930 }
931
932 static void SampleMiPaste (void)
933 {
934         /* routine when (sub)item "Paste" is selected. */
935 }
936
937 static void SampleMiPoints (void)
938 {
939         GuiSwitches.SampDrawMode = SAMP_PIXEL;
940         UpdateSampGraph();
941 }
942
943 static void SampleMiLines (void)
944 {
945         GuiSwitches.SampDrawMode = SAMP_LINE;
946         UpdateSampGraph();
947 }
948
949 static void SampleMiFilled (void)
950 {
951         GuiSwitches.SampDrawMode = SAMP_FILLED;
952         UpdateSampGraph();
953 }